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