From 02215794949b4244278ef305fc0698acb9761da5 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Fri, 17 Jul 2020 13:20:11 -0500 Subject: [PATCH 1/5] Test: DOMNodeComparator fails using namespace uri as xml entity Related to https://github.com/sebastianbergmann/comparator/issues/87 --- tests/DOMNodeComparatorTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/DOMNodeComparatorTest.php b/tests/DOMNodeComparatorTest.php index 8d52fc2..46a5ba8 100644 --- a/tests/DOMNodeComparatorTest.php +++ b/tests/DOMNodeComparatorTest.php @@ -84,6 +84,14 @@ public function assertEqualsSucceedsProvider() $this->createDOMDocument(""), $this->createDOMDocument(""), ], + [ + $this->createDOMDocument( + ']>' + ), + $this->createDOMDocument( + ']>' + ), + ], ]; } @@ -118,6 +126,15 @@ public function assertEqualsFailsProvider() $this->createDOMDocument(' bar '), $this->createDOMDocument(' BAR '), ], + [ + $this->createDOMDocument( + ']>' + ), + $this->createDOMDocument( + ']>' . + '' + ), + ], ]; } From c73b08aa001a0513d3c636274a20c5ae5e774295 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Fri, 17 Jul 2020 13:21:49 -0500 Subject: [PATCH 2/5] Fix compare DOMDocument that used xml namespace uri as entity If C14N fails it retry no to text conversion without canonicalization --- src/DOMNodeComparator.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/DOMNodeComparator.php b/src/DOMNodeComparator.php index 5b8629c..507c6a6 100644 --- a/src/DOMNodeComparator.php +++ b/src/DOMNodeComparator.php @@ -70,8 +70,15 @@ public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = f private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase): string { if ($canonicalize) { + /** @psalm-var string|false $c14n */ + $c14n = @$node->C14N(); + + if ($c14n === false) { // try node-to-text without canonicalize + return $this->nodeToText($node, !$canonicalize, $ignoreCase); + } + $document = new DOMDocument; - @$document->loadXML($node->C14N()); + @$document->loadXML($c14n); $node = $document; } From c14a62d40beb96c9f75bd9ae7e14ce578dc244f3 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 3 Aug 2020 21:48:34 -0500 Subject: [PATCH 3/5] move breaking c14n cases to its own providers and tests reuse testAssertEqualsSucceeds and testAssertEqualsFails --- tests/DOMNodeComparatorTest.php | 63 +++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/tests/DOMNodeComparatorTest.php b/tests/DOMNodeComparatorTest.php index 46a5ba8..6a30e0c 100644 --- a/tests/DOMNodeComparatorTest.php +++ b/tests/DOMNodeComparatorTest.php @@ -84,14 +84,6 @@ public function assertEqualsSucceedsProvider() $this->createDOMDocument(""), $this->createDOMDocument(""), ], - [ - $this->createDOMDocument( - ']>' - ), - $this->createDOMDocument( - ']>' - ), - ], ]; } @@ -126,18 +118,53 @@ public function assertEqualsFailsProvider() $this->createDOMDocument(' bar '), $this->createDOMDocument(' BAR '), ], + ]; + } + + public function assertEqualsSucceedsWithNonCanonicalizableNodesProvider() + { + $document = new DOMDocument; + + return [ + [$document, new DOMDocument], + [$document->createElement('foo'), $document->createElement('foo')], [ $this->createDOMDocument( ']>' ), $this->createDOMDocument( - ']>' . - '' + ']>' ), ], ]; } + public function assertEqualsFailsWithNonCanonicalizableNodesProvider() + { + // empty document makes C14N return empty string + $document = new DOMDocument; + + // nodes created but not appended to the document makes C14N return empty string + $nodeFoo = $document->createElement('foo'); + $nodeBar = $document->createElement('bar'); + + // documents with xmlns definitions to xml entities makes C14N return false + $documentNsUriIsEntityFoo = $this->createDOMDocument( // root element is i:foo + ']>' + ); + $documentNsUriIsEntityBar = $this->createDOMDocument( // root element is i:bar + ']>' + ); + + return [ + [$document, $nodeFoo], + [$document, $documentNsUriIsEntityFoo], + [$nodeFoo, $nodeBar], + [$nodeFoo, $documentNsUriIsEntityFoo], + [$documentNsUriIsEntityFoo, $documentNsUriIsEntityBar], + ]; + } + /** * @dataProvider acceptsSucceedsProvider */ @@ -186,6 +213,22 @@ public function testAssertEqualsFails($expected, $actual): void $this->comparator->assertEquals($expected, $actual); } + /** + * @dataProvider assertEqualsSucceedsWithNonCanonicalizableNodesProvider + */ + public function testAssertEqualsSucceedsWithNonCanonicalizableNodes($expected, $actual): void + { + $this->testAssertEqualsSucceeds($expected, $actual); + } + + /** + * @dataProvider assertEqualsFailsWithNonCanonicalizableNodesProvider + */ + public function testAssertEqualsFailsWithNonCanonicalizableNodes($expected, $actual): void + { + $this->testAssertEqualsFails($expected, $actual); + } + private function createDOMDocument($content) { $document = new DOMDocument; From f742b81d875dfd6d9559a44f7d22d95221a81232 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 3 Aug 2020 21:49:44 -0500 Subject: [PATCH 4/5] when c14n fail (false or empty) do nodeToText without canonicalization --- src/DOMNodeComparator.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/DOMNodeComparator.php b/src/DOMNodeComparator.php index 507c6a6..a1aa225 100644 --- a/src/DOMNodeComparator.php +++ b/src/DOMNodeComparator.php @@ -73,8 +73,8 @@ private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase) /** @psalm-var string|false $c14n */ $c14n = @$node->C14N(); - if ($c14n === false) { // try node-to-text without canonicalize - return $this->nodeToText($node, !$canonicalize, $ignoreCase); + if ($c14n === false || $c14n === '') { // try node-to-text without canonicalize + return $this->nodeToText($node, false, $ignoreCase); } $document = new DOMDocument; From c0f0b585db035e606032301e25cd9b1363c0bce1 Mon Sep 17 00:00:00 2001 From: Carlos C Soto Date: Mon, 3 Aug 2020 21:51:12 -0500 Subject: [PATCH 5/5] remove error suppression on DOMDocument::loadXML --- src/DOMNodeComparator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DOMNodeComparator.php b/src/DOMNodeComparator.php index a1aa225..fa642ab 100644 --- a/src/DOMNodeComparator.php +++ b/src/DOMNodeComparator.php @@ -78,7 +78,7 @@ private function nodeToText(DOMNode $node, bool $canonicalize, bool $ignoreCase) } $document = new DOMDocument; - @$document->loadXML($c14n); + $document->loadXML($c14n); $node = $document; }