Skip to content

Fix XML Equality Check by Comparing Parsed XML Structure Instead of Raw Strings #3166

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from

Conversation

omidmloo
Copy link

Fix XML Equality Check by Comparing Parsed XML Structure Instead of Raw Strings

Summary of the changes
Ensures XML comparisons are based on structure instead of raw string equality.

Description

Previously, the test compared XML as raw strings, which caused false negatives due to formatting differences, whitespace, and attribute order. While the expected result was different, the discrepancies were due to formatting rather than actual content differences. This fix ensures XML elements are compared meaningfully, preventing incorrect failures.

Fixes & Improvements:

  • Type-Aware XML Comparison:
    • Introduced a dictionary-based approach to compare XML elements based on their specific types.
    • Added AreXmlsEqual to handle XML documents as objects rather than raw strings.
    • Ensured XML comparisons focus on element structure rather than text differences.
  • More Robust Equality Checks:
    • Improved handling of various security and identity-related XML types.
    • Avoids false negatives caused by minor formatting discrepancies.
  • Enhanced Debugging & Maintainability:
    • Clearer difference tracking when mismatches occur.
    • Improved logging of discrepancies between expected and actual XML structures.

Fixes #3159

@omidmloo omidmloo requested a review from a team as a code owner March 11, 2025 20:26
@pmaytak pmaytak requested a review from Copilot March 12, 2025 05:23
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves XML equality comparisons by introducing a type-aware, structure-based check for XML documents, fixing false negatives caused by formatting differences. Key changes include:

  • Adding a new AreXmlsEqual method for comparing XDocument objects.
  • Incorporating the new XML comparison function into the equality dictionary.
  • Updating tests to use XDocument-based comparisons instead of raw string comparisons.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
test/Microsoft.IdentityModel.TestUtils/IdentityComparer.cs Introduces XML comparison functions and updates equality logic to support XDocument.
test/Microsoft.IdentityModel.Xml.Tests/DSigSerializerTests.cs Modifies tests to compare XML by parsing into XDocument.
Comments suppressed due to low confidence (2)

test/Microsoft.IdentityModel.TestUtils/IdentityComparer.cs:1189

  • The AreXmlsEqual method adds a diff message when xml1 is null but does not return false, which can lead to a NullReferenceException when xml1.Root is accessed later. Consider returning false immediately after detecting a null xml1 and include a properly formatted error message.
if (xml1 == null) localContext.Diffs.Add($"({name1} == null, {name2} == {xml2.ToString()}." );

test/Microsoft.IdentityModel.TestUtils/IdentityComparer.cs:1192

  • Similar to the null check for xml1, if xml2 is null the method only adds a diff message without returning false, which may cause a NullReferenceException when xml2.Root is accessed. Consider returning false immediately and correcting the error message formatting.
if (xml2 == null) localContext.Diffs.Add($"({name1} == {xml1.ToString()}, {name2} == null." );

/// <param name="elem2">The second XML element to compare.</param>
/// <param name="localContext"></param>
/// <returns>True if the elements are considered equal, otherwise false.</returns>
private static bool CompareXmlElements(XElement elem1, XElement elem2, CompareContext localContext)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider utilizing localContext to add information about the differences found which could help with debugging.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// Compare the original XML with the re-serialized XML.
// Parsing the XML strings into XDocument ensures that the comparison is based on
// structural and content equality rather than raw string differences (formatting, whitespace,...).
IdentityComparer.AreEqual(XDocument.Parse(theoryData.Xml), XDocument.Parse(xml), context);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding tests for different xml structures and null values to verify IdentityComparer behaves as expected when comparing XML.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Sruke, thank you for the review. Since these tests focus on IdentityComparer, would it be better to add them to a new test file for better organization, or should I extend the existing test file? Let me know your preference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that creating a new file is better for organization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Incorrect Test Data in WriteKeyInfoTheoryData (Microsoft.IdentityModel.Xml.Tests)
3 participants