Skip to content

Make XmlDiff compliant with the XML spec - #395

Open
rmunn wants to merge 1 commit into
masterfrom
bugfix/normalize-whitespace-in-xmldiff
Open

Make XmlDiff compliant with the XML spec#395
rmunn wants to merge 1 commit into
masterfrom
bugfix/normalize-whitespace-in-xmldiff

Conversation

@rmunn

@rmunn rmunn commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

XML spec section 2.11 requires end-of-line characters to be normalized to LF, and whitespace inside attributes to be normalized to spaces (no tabs, CR, or LF characters). Our current XmlDiff implementation would find diffs where none should be found, and this will fix that bug.

Fixes #361.

This would probably also have fixed the bug that 01b27ec was trying to fix, though I haven't verified that yet.


This change is Reviewable

XML spec section 2.11 requires end-of-line characters to be normalized
to LF, and whitespace inside attributes to be normalized to spaces (no
tabs, CR, or LF characters). Our current XmlDiff implementation would
find diffs where none should be found, and this will fix that bug.
@rmunn rmunn self-assigned this Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

Test Results

       8 files  ±0     334 suites  ±0   2h 28m 2s ⏱️ + 1m 48s
1 008 tests ±0     952 ✔️ ±0    56 💤 ±0  0 ±0 
3 197 runs  ±0  3 074 ✔️ ±0  123 💤 ±0  0 ±0 

Results for commit 21fe332. ± Comparison against base commit c2c1e42.

♻️ This comment has been updated with latest results.

@rmunn

rmunn commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

It looks like the 01b27ec bugfix is just an illusion caused by a bad test assertion. If you remove 01b27ec then one test fails, the EnsureMergedCData_IsRetained test in ChorusNotesFileHandlerTests. But what that test is doing is doing the same merge the "old way" and the "new way" and then comparing the merge results by a string comparison. Thing is, without the 01b27ec change (which just sets WhitespaceHandling = None) the "old way" and the "new way" differ in whitespace. Specifically, whitespace between XML elements where it's not semantically significant. In other words, the "old way" results in this:

<?xml version="1.0" ... ?>
<notes version="0">
    <annotation ...>
        <message ...>

And the "new way" results in this:

<?xml version="1.0" ... ?>
<notes version="0">

    <annotation ...>

        <message ...>

Those extra newlines between XML elements are not semantically significant, and so the test should have compared them and concluded they were equal. Yet it's using a string comparison, and \n< vs \n\n< are different bytes, so the comparison fails.

I'll leave 01b27ec in, because it's been in place for over a decade and a half and there's no point in removing it now. And I won't change the EnsureMergedCData_IsRetained test now. But it's a poor test, checking the wrong thing, and failing on a false positive.

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.

Failing unit test on master branch (since at least 2022)

1 participant