1--TEST-- 2DOMXPath::query() can return DOMNodeList with DOMNameSpaceNode items - advanced variation 3--EXTENSIONS-- 4dom 5--FILE-- 6<?php 7 8$dom = new DOMDocument(); 9$dom->loadXML(<<<'XML' 10<root xmlns:foo="http://example.com/foo" xmlns:bar="http://example.com/bar"> 11 <child xmlns:baz="http://example.com/baz">Hello PHP!</child> 12</root> 13XML); 14 15$xpath = new DOMXPath($dom); 16$query = '//namespace::*'; 17 18echo "-- All namespace attributes --\n"; 19 20foreach ($xpath->query($query) as $attribute) { 21 echo $attribute->nodeName . ' = ' . $attribute->nodeValue . PHP_EOL; 22 var_dump($attribute->parentNode->tagName); 23} 24 25echo "-- All namespace attributes with removal attempt --\n"; 26 27foreach ($xpath->query($query) as $attribute) { 28 echo "Before: ", $attribute->parentNode->tagName, "\n"; 29 // Second & third attempt should fail because it's no longer in the document 30 try { 31 $attribute->parentNode->remove(); 32 } catch (\DOMException $e) { 33 echo $e->getMessage(), "\n"; 34 } 35 // However, it should not cause a use-after-free 36 echo "After: ", $attribute->parentNode->tagName, "\n"; 37} 38 39?> 40--EXPECT-- 41-- All namespace attributes -- 42xmlns:xml = http://www.w3.org/XML/1998/namespace 43string(4) "root" 44xmlns:bar = http://example.com/bar 45string(4) "root" 46xmlns:foo = http://example.com/foo 47string(4) "root" 48xmlns:xml = http://www.w3.org/XML/1998/namespace 49string(5) "child" 50xmlns:bar = http://example.com/bar 51string(5) "child" 52xmlns:foo = http://example.com/foo 53string(5) "child" 54xmlns:baz = http://example.com/baz 55string(5) "child" 56-- All namespace attributes with removal attempt -- 57Before: root 58After: root 59Before: root 60Not Found Error 61After: root 62Before: root 63Not Found Error 64After: root 65Before: child 66After: child 67Before: child 68Not Found Error 69After: child 70Before: child 71Not Found Error 72After: child 73Before: child 74Not Found Error 75After: child 76