Skip to content

Commit 5c8c72b

Browse files
committed
bug symfony#59779 [DomCrawler] Bug symfony#43921 Check for null parent nodes in the case of orphaned branches (ttk)
This PR was submitted for the 7.2 branch but it was merged into the 6.4 branch instead. Discussion ---------- [DomCrawler] Bug symfony#43921 Check for null parent nodes in the case of orphaned branches | Q | A | ------------- | --- | Branch | 7.2 | Bug fix | yes | New feature | no | Deprecations | no | Issues | Fix symfony#43921 | License | MIT This simple fix checks for null parent nodes when traversing the DOM tree when calling the `closest()` function. Instead of failing, the function will return null instead. This bring it into alignment with how the `ancestors()` function behaves (not failing on null parent nodes). Null parent nodes can occur when a DOM branch is orphaned due to manipulations on the document, and this is a perfectly normal scenario. Unit tests added that checks for this specific bug. This fix should not break any backward compatibility. Commits ------- 9a98452 Check for null parent Nodes in the case of orphaned branches
2 parents f5b66b5 + 9a98452 commit 5c8c72b

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/Symfony/Component/DomCrawler/Crawler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ public function closest(string $selector): ?self
431431

432432
$domNode = $this->getNode(0);
433433

434-
while (\XML_ELEMENT_NODE === $domNode->nodeType) {
434+
while (null !== $domNode && \XML_ELEMENT_NODE === $domNode->nodeType) {
435435
$node = $this->createSubCrawler($domNode);
436436
if ($node->matches($selector)) {
437437
return $node;

src/Symfony/Component/DomCrawler/Tests/AbstractCrawlerTestCase.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,29 @@ public function testClosest()
10311031
$this->assertNull($notFound);
10321032
}
10331033

1034+
public function testClosestWithOrphanedNode()
1035+
{
1036+
$html = <<<'HTML'
1037+
<html lang="en">
1038+
<body>
1039+
<div id="foo" class="newFoo ok">
1040+
<div class="lorem1 ko"></div>
1041+
</div>
1042+
</body>
1043+
</html>
1044+
HTML;
1045+
1046+
$crawler = $this->createCrawler($this->getDoctype().$html);
1047+
$foo = $crawler->filter('#foo');
1048+
1049+
$fooNode = $foo->getNode(0);
1050+
1051+
$fooNode->parentNode->replaceChild($fooNode->ownerDocument->createElement('ol'), $fooNode);
1052+
1053+
$body = $foo->closest('body');
1054+
$this->assertNull($body);
1055+
}
1056+
10341057
public function testOuterHtml()
10351058
{
10361059
$html = <<<'HTML'

0 commit comments

Comments
 (0)