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