Skip to content

Commit 9f362a1

Browse files
committed
Prevent adding non-DOMElement elements in DomCrawler
Many methods of the DomCrawler component are relying on the DOMElement API, not only on the DOMNode API.
1 parent 99745e1 commit 9f362a1

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

src/Symfony/Component/DomCrawler/Crawler.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,14 @@ public function addNodes(array $nodes)
308308
public function addNode(\DOMNode $node)
309309
{
310310
if ($node instanceof \DOMDocument) {
311-
parent::attach($node->documentElement);
312-
} else {
313-
parent::attach($node);
311+
$node = $node->documentElement;
312+
}
313+
314+
if (!$node instanceof \DOMElement) {
315+
throw new \InvalidArgumentException(sprintf('Nodes set in a Crawler must be DOMElement or DOMDocument instances, "%s" given.', get_class($node)));
314316
}
317+
318+
parent::attach($node);
315319
}
316320

317321
// Serializing and unserializing a crawler creates DOM objects in a corrupted state. DOM elements are not properly serializable.
@@ -974,7 +978,12 @@ private function filterRelativeXPath($xpath)
974978

975979
foreach ($this as $node) {
976980
$domxpath = $this->createDOMXPath($node->ownerDocument, $prefixes);
977-
$crawler->add($domxpath->query($xpath, $node));
981+
982+
foreach ($domxpath->query($xpath, $node) as $subNode) {
983+
if ($subNode->nodeType === 1) {
984+
$crawler->add($subNode);
985+
}
986+
}
978987
}
979988

980989
return $crawler;

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

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ public function testConstructor()
2020
$crawler = new Crawler();
2121
$this->assertCount(0, $crawler, '__construct() returns an empty crawler');
2222

23-
$crawler = new Crawler(new \DOMNode());
23+
$doc = new \DOMDocument();
24+
$node = $doc->createElement('test');
25+
26+
$crawler = new Crawler($node);
2427
$this->assertCount(1, $crawler, '__construct() takes a node as a first argument');
2528
}
2629

@@ -37,6 +40,7 @@ public function testAdd()
3740
$crawler->add($this->createNodeList());
3841
$this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMNodeList');
3942

43+
$list = array();
4044
foreach ($this->createNodeList() as $node) {
4145
$list[] = $node;
4246
}
@@ -56,12 +60,22 @@ public function testAdd()
5660
/**
5761
* @expectedException \InvalidArgumentException
5862
*/
59-
public function testAddInvalidNode()
63+
public function testAddInvalidType()
6064
{
6165
$crawler = new Crawler();
6266
$crawler->add(1);
6367
}
6468

69+
/**
70+
* @expectedException \InvalidArgumentException
71+
* @expectedExceptionMessage Nodes set in a Crawler must be DOMElement or DOMDocument instances, "DOMNode" given.
72+
*/
73+
public function testAddInvalidNode()
74+
{
75+
$crawler = new Crawler();
76+
$crawler->add(new \DOMNode());
77+
}
78+
6579
/**
6680
* @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent
6781
*/
@@ -267,6 +281,7 @@ public function testAddNodeList()
267281
*/
268282
public function testAddNodes()
269283
{
284+
$list = array();
270285
foreach ($this->createNodeList() as $node) {
271286
$list[] = $node;
272287
}
@@ -290,7 +305,10 @@ public function testAddNode()
290305

291306
public function testClear()
292307
{
293-
$crawler = new Crawler(new \DOMNode());
308+
$doc = new \DOMDocument();
309+
$node = $doc->createElement('test');
310+
311+
$crawler = new Crawler($node);
294312
$crawler->clear();
295313
$this->assertCount(0, $crawler, '->clear() removes all the nodes from the crawler');
296314
}
@@ -526,7 +544,7 @@ public function testFilterXPathWithAttributeAxis()
526544

527545
public function testFilterXPathWithAttributeAxisAfterElementAxis()
528546
{
529-
$this->assertCount(3, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis');
547+
$this->assertCount(0, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis');
530548
}
531549

532550
public function testFilterXPathWithChildAxis()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy