diff --git a/NEWS b/NEWS index df641212d5f..91331aadba9 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,7 @@ PHP NEWS . Fix weird unpack behaviour in DOM. (nielsdos) . Fixed bug GH-18090 (DOM: Svg attributes and tag names are being lowercased). (nielsdos) + . Fix xinclude destruction of live attributes. (nielsdos) - Fuzzer: . Fixed bug GH-18081 (Memory leaks in error paths of fuzzer SAPI). diff --git a/ext/dom/document.c b/ext/dom/document.c index aed65630d25..2abf6636713 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -1669,14 +1669,28 @@ PHP_METHOD(Dom_XMLDocument, saveXml) } /* }}} end dom_document_savexml */ +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 c32263bfe24..b2c4caff2fc 100644 --- a/ext/dom/tests/gh17847.phpt +++ b/ext/dom/tests/gh17847.phpt @@ -13,7 +13,7 @@ $doc->loadXML(<< -

garbage

+

garbage

@@ -22,20 +22,31 @@ 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(); foreach ($garbage as $node) { - try { - var_dump($node->localName); - } catch (DOMException $e) { - echo $e->getMessage(), "\n"; - } + try { + var_dump($node->localName); + } catch (DOMException $e) { + echo $e->getMessage(), "\n"; + } } ?> --EXPECT-- Invalid State Error Invalid State Error Invalid State Error +Invalid State Error +Invalid State Error +Invalid State Error +Invalid State Error