Skip to content

Commit 7ff940f

Browse files
authored
Fix GH-16356: Segmentation fault with $outerHTML and next node (#16364)
`$outerHTML` should only serialize the current node, not its siblings.
1 parent 2b39e72 commit 7ff940f

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

ext/dom/inner_outer_html_mixin.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,15 @@ zend_result dom_element_outer_html_read(dom_object *obj, zval *retval)
392392
element.doc = this->doc;
393393

394394
xmlNodePtr old_parent = this->parent;
395+
xmlNodePtr old_next = this->next;
395396
this->parent = &element;
397+
this->next = NULL;
396398

397399
/* 2. Return the result of running fragment serializing algorithm steps with element and true. */
398400
zend_string *serialization = dom_element_html_fragment_serialize(obj, &element);
399401

400402
this->parent = old_parent;
403+
this->next = old_next;
401404

402405
if (serialization == NULL) {
403406
return FAILURE;

ext/dom/tests/gh16356.phpt

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
--TEST--
2+
GH-16356 (Segmentation fault with $outerHTML and next node)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
8+
$dom = Dom\HTMLDocument::createEmpty();
9+
$dom->append($dom->createElement("container"));
10+
$e1 = $dom->documentElement->appendChild($dom->createElementNS("urn:example1", "example:foo"));
11+
$e2 = $dom->documentElement->appendChild($dom->createElementNS("urn:example2", "example:foo"));
12+
var_dump($e1, $e2);
13+
14+
?>
15+
--EXPECT--
16+
object(Dom\Element)#3 (30) {
17+
["namespaceURI"]=>
18+
string(12) "urn:example1"
19+
["prefix"]=>
20+
string(7) "example"
21+
["localName"]=>
22+
string(3) "foo"
23+
["tagName"]=>
24+
string(11) "example:foo"
25+
["id"]=>
26+
string(0) ""
27+
["className"]=>
28+
string(0) ""
29+
["classList"]=>
30+
string(22) "(object value omitted)"
31+
["attributes"]=>
32+
string(22) "(object value omitted)"
33+
["firstElementChild"]=>
34+
NULL
35+
["lastElementChild"]=>
36+
NULL
37+
["childElementCount"]=>
38+
int(0)
39+
["previousElementSibling"]=>
40+
NULL
41+
["nextElementSibling"]=>
42+
string(22) "(object value omitted)"
43+
["innerHTML"]=>
44+
string(0) ""
45+
["outerHTML"]=>
46+
string(27) "<example:foo></example:foo>"
47+
["substitutedNodeValue"]=>
48+
string(0) ""
49+
["nodeType"]=>
50+
int(1)
51+
["nodeName"]=>
52+
string(11) "example:foo"
53+
["baseURI"]=>
54+
string(11) "about:blank"
55+
["isConnected"]=>
56+
bool(true)
57+
["ownerDocument"]=>
58+
string(22) "(object value omitted)"
59+
["parentNode"]=>
60+
string(22) "(object value omitted)"
61+
["parentElement"]=>
62+
string(22) "(object value omitted)"
63+
["childNodes"]=>
64+
string(22) "(object value omitted)"
65+
["firstChild"]=>
66+
NULL
67+
["lastChild"]=>
68+
NULL
69+
["previousSibling"]=>
70+
NULL
71+
["nextSibling"]=>
72+
string(22) "(object value omitted)"
73+
["nodeValue"]=>
74+
NULL
75+
["textContent"]=>
76+
string(0) ""
77+
}
78+
object(Dom\Element)#4 (30) {
79+
["namespaceURI"]=>
80+
string(12) "urn:example2"
81+
["prefix"]=>
82+
string(7) "example"
83+
["localName"]=>
84+
string(3) "foo"
85+
["tagName"]=>
86+
string(11) "example:foo"
87+
["id"]=>
88+
string(0) ""
89+
["className"]=>
90+
string(0) ""
91+
["classList"]=>
92+
string(22) "(object value omitted)"
93+
["attributes"]=>
94+
string(22) "(object value omitted)"
95+
["firstElementChild"]=>
96+
NULL
97+
["lastElementChild"]=>
98+
NULL
99+
["childElementCount"]=>
100+
int(0)
101+
["previousElementSibling"]=>
102+
string(22) "(object value omitted)"
103+
["nextElementSibling"]=>
104+
NULL
105+
["innerHTML"]=>
106+
string(0) ""
107+
["outerHTML"]=>
108+
string(27) "<example:foo></example:foo>"
109+
["substitutedNodeValue"]=>
110+
string(0) ""
111+
["nodeType"]=>
112+
int(1)
113+
["nodeName"]=>
114+
string(11) "example:foo"
115+
["baseURI"]=>
116+
string(11) "about:blank"
117+
["isConnected"]=>
118+
bool(true)
119+
["ownerDocument"]=>
120+
string(22) "(object value omitted)"
121+
["parentNode"]=>
122+
string(22) "(object value omitted)"
123+
["parentElement"]=>
124+
string(22) "(object value omitted)"
125+
["childNodes"]=>
126+
string(22) "(object value omitted)"
127+
["firstChild"]=>
128+
NULL
129+
["lastChild"]=>
130+
NULL
131+
["previousSibling"]=>
132+
string(22) "(object value omitted)"
133+
["nextSibling"]=>
134+
NULL
135+
["nodeValue"]=>
136+
NULL
137+
["textContent"]=>
138+
string(0) ""
139+
}

0 commit comments

Comments
 (0)