diff --git a/ext/dom/document.c b/ext/dom/document.c index 0388249766e1f..42d67d5739845 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1607,14 +1607,28 @@ static zend_always_inline xmlNodePtr php_dom_next_in_tree_order(const xmlNode *n } } +static void dom_xinclude_strip_references_for_attributes(xmlNodePtr basep) +{ + for (xmlAttrPtr prop = basep->properties; prop; prop = prop->next) { + php_libxml_node_free_resource((xmlNodePtr) prop); + for (xmlNodePtr child = prop->children; child; child = child->next) { + php_libxml_node_free_resource(child); + } + } +} + static void dom_xinclude_strip_references(xmlNodePtr basep) { php_libxml_node_free_resource(basep); + dom_xinclude_strip_references_for_attributes(basep); xmlNodePtr current = basep->children; while (current) { php_libxml_node_free_resource(current); + if (current->type == XML_ELEMENT_NODE) { + dom_xinclude_strip_references_for_attributes(current); + } current = php_dom_next_in_tree_order(current, basep); } } diff --git a/ext/dom/tests/gh17847.phpt b/ext/dom/tests/gh17847.phpt index 5d5df0b3be05f..01601ca035265 100644 --- a/ext/dom/tests/gh17847.phpt +++ b/ext/dom/tests/gh17847.phpt @@ -13,7 +13,7 @@ $doc->loadXML(<< -

garbage

+

garbage

@@ -22,15 +22,22 @@ XML); $xpath = new DOMXPath($doc); $garbage = []; -foreach ($xpath->query('//p') as $entry) +foreach ($xpath->query('//p') as $entry) { $garbage[] = $entry; + foreach ($entry->attributes as $attr) { + $garbage[] = $attr; + foreach ($attr->childNodes as $child) { + $garbage[] = $child; + } + } +} @$doc->xinclude(); var_dump($garbage); ?> --EXPECT-- -array(3) { +array(7) { [0]=> object(DOMElement)#3 (1) { ["schemaTypeInfo"]=> @@ -46,4 +53,24 @@ array(3) { ["schemaTypeInfo"]=> NULL } + [3]=> + object(DOMAttr)#10 (2) { + ["specified"]=> + bool(true) + ["schemaTypeInfo"]=> + NULL + } + [4]=> + object(DOMText)#13 (0) { + } + [5]=> + object(DOMAttr)#12 (2) { + ["specified"]=> + bool(true) + ["schemaTypeInfo"]=> + NULL + } + [6]=> + object(DOMText)#15 (0) { + } }