From 9f362a12f616984676182f69aab18c662b47445d Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Fri, 2 Oct 2015 01:09:43 +0200 Subject: [PATCH] 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. --- src/Symfony/Component/DomCrawler/Crawler.php | 17 +++++++++--- .../DomCrawler/Tests/CrawlerTest.php | 26 ++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/DomCrawler/Crawler.php b/src/Symfony/Component/DomCrawler/Crawler.php index d4e452f6f0dd2..cd9ede0a244d0 100644 --- a/src/Symfony/Component/DomCrawler/Crawler.php +++ b/src/Symfony/Component/DomCrawler/Crawler.php @@ -308,10 +308,14 @@ public function addNodes(array $nodes) public function addNode(\DOMNode $node) { if ($node instanceof \DOMDocument) { - parent::attach($node->documentElement); - } else { - parent::attach($node); + $node = $node->documentElement; + } + + if (!$node instanceof \DOMElement) { + throw new \InvalidArgumentException(sprintf('Nodes set in a Crawler must be DOMElement or DOMDocument instances, "%s" given.', get_class($node))); } + + parent::attach($node); } // 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) foreach ($this as $node) { $domxpath = $this->createDOMXPath($node->ownerDocument, $prefixes); - $crawler->add($domxpath->query($xpath, $node)); + + foreach ($domxpath->query($xpath, $node) as $subNode) { + if ($subNode->nodeType === 1) { + $crawler->add($subNode); + } + } } return $crawler; diff --git a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php index cdd87dd7a8d1c..8a25d0b950bf5 100755 --- a/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php +++ b/src/Symfony/Component/DomCrawler/Tests/CrawlerTest.php @@ -20,7 +20,10 @@ public function testConstructor() $crawler = new Crawler(); $this->assertCount(0, $crawler, '__construct() returns an empty crawler'); - $crawler = new Crawler(new \DOMNode()); + $doc = new \DOMDocument(); + $node = $doc->createElement('test'); + + $crawler = new Crawler($node); $this->assertCount(1, $crawler, '__construct() takes a node as a first argument'); } @@ -37,6 +40,7 @@ public function testAdd() $crawler->add($this->createNodeList()); $this->assertEquals('foo', $crawler->filterXPath('//div')->attr('class'), '->add() adds nodes from a \DOMNodeList'); + $list = array(); foreach ($this->createNodeList() as $node) { $list[] = $node; } @@ -56,12 +60,22 @@ public function testAdd() /** * @expectedException \InvalidArgumentException */ - public function testAddInvalidNode() + public function testAddInvalidType() { $crawler = new Crawler(); $crawler->add(1); } + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Nodes set in a Crawler must be DOMElement or DOMDocument instances, "DOMNode" given. + */ + public function testAddInvalidNode() + { + $crawler = new Crawler(); + $crawler->add(new \DOMNode()); + } + /** * @covers Symfony\Component\DomCrawler\Crawler::addHtmlContent */ @@ -267,6 +281,7 @@ public function testAddNodeList() */ public function testAddNodes() { + $list = array(); foreach ($this->createNodeList() as $node) { $list[] = $node; } @@ -290,7 +305,10 @@ public function testAddNode() public function testClear() { - $crawler = new Crawler(new \DOMNode()); + $doc = new \DOMDocument(); + $node = $doc->createElement('test'); + + $crawler = new Crawler($node); $crawler->clear(); $this->assertCount(0, $crawler, '->clear() removes all the nodes from the crawler'); } @@ -526,7 +544,7 @@ public function testFilterXPathWithAttributeAxis() public function testFilterXPathWithAttributeAxisAfterElementAxis() { - $this->assertCount(3, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis'); + $this->assertCount(0, $this->createTestCrawler()->filterXPath('//form/button/attribute::*'), '->filterXPath() handles attribute axes properly when they are preceded by an element filtering axis'); } public function testFilterXPathWithChildAxis() 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