@@ -1669,47 +1669,6 @@ PHP_METHOD(Dom_XMLDocument, saveXml)
16691669}
16701670/* }}} end dom_document_savexml */
16711671
1672- static xmlNodePtr php_dom_free_xinclude_node (xmlNodePtr cur ) /* {{{ */
1673- {
1674- xmlNodePtr xincnode ;
1675-
1676- xincnode = cur ;
1677- cur = cur -> next ;
1678- xmlUnlinkNode (xincnode );
1679- php_libxml_node_free_resource (xincnode );
1680-
1681- return cur ;
1682- }
1683- /* }}} */
1684-
1685- static void php_dom_remove_xinclude_nodes (xmlNodePtr cur ) /* {{{ */
1686- {
1687- while (cur ) {
1688- if (cur -> type == XML_XINCLUDE_START ) {
1689- cur = php_dom_free_xinclude_node (cur );
1690-
1691- /* XML_XINCLUDE_END node will be a sibling of XML_XINCLUDE_START */
1692- while (cur && cur -> type != XML_XINCLUDE_END ) {
1693- /* remove xinclude processing nodes from recursive xincludes */
1694- if (cur -> type == XML_ELEMENT_NODE ) {
1695- php_dom_remove_xinclude_nodes (cur -> children );
1696- }
1697- cur = cur -> next ;
1698- }
1699-
1700- if (cur && cur -> type == XML_XINCLUDE_END ) {
1701- cur = php_dom_free_xinclude_node (cur );
1702- }
1703- } else {
1704- if (cur -> type == XML_ELEMENT_NODE ) {
1705- php_dom_remove_xinclude_nodes (cur -> children );
1706- }
1707- cur = cur -> next ;
1708- }
1709- }
1710- }
1711- /* }}} */
1712-
17131672static void dom_xinclude_strip_references (xmlNodePtr basep )
17141673{
17151674 php_libxml_node_free_resource (basep );
@@ -1722,17 +1681,19 @@ static void dom_xinclude_strip_references(xmlNodePtr basep)
17221681 }
17231682}
17241683
1725- /* See GH-14702.
1726- * We have to remove userland references to xinclude fallback nodes because libxml2 will make clones of these
1684+ /* See GH-14702 and GH-17847 .
1685+ * We have to remove userland references to xinclude nodes because libxml2 will make clones of these
17271686 * and remove the original nodes. If the originals are removed while there are still userland references
17281687 * this will cause memory corruption. */
17291688static void dom_xinclude_strip_fallback_references (const xmlNode * basep )
17301689{
17311690 xmlNodePtr current = basep -> children ;
17321691
1692+ /* TODO: try to improve loop search performance */
17331693 while (current ) {
1734- if (current -> type == XML_ELEMENT_NODE && current -> ns != NULL && current -> _private != NULL
1735- && xmlStrEqual (current -> name , XINCLUDE_FALLBACK )
1694+ if (current -> type == XML_ELEMENT_NODE
1695+ && current -> ns != NULL
1696+ && xmlStrEqual (current -> name , XINCLUDE_NODE )
17361697 && (xmlStrEqual (current -> ns -> href , XINCLUDE_NS ) || xmlStrEqual (current -> ns -> href , XINCLUDE_OLD_NS ))) {
17371698 dom_xinclude_strip_references (current );
17381699 }
@@ -1745,22 +1706,11 @@ static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long fl
17451706{
17461707 dom_xinclude_strip_fallback_references ((const xmlNode * ) docp );
17471708
1709+ flags |= XML_PARSE_NOXINCNODE ;
17481710 PHP_LIBXML_SANITIZE_GLOBALS (xinclude );
17491711 int err = xmlXIncludeProcessFlags (docp , (int )flags );
17501712 PHP_LIBXML_RESTORE_GLOBALS (xinclude );
17511713
1752- /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
1753- are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
1754- but are not wanted in resulting document - must be done even if err as it could fail after
1755- having processed some xincludes */
1756- xmlNodePtr root = docp -> children ;
1757- while (root && root -> type != XML_ELEMENT_NODE && root -> type != XML_XINCLUDE_START ) {
1758- root = root -> next ;
1759- }
1760- if (root ) {
1761- php_dom_remove_xinclude_nodes (root );
1762- }
1763-
17641714 php_libxml_invalidate_node_list_cache (intern -> document );
17651715
17661716 return err ;
0 commit comments