Thanks to visit codestin.com
Credit goes to github.com

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)