@@ -1706,9 +1706,41 @@ static void php_dom_remove_xinclude_nodes(xmlNodePtr cur) /* {{{ */
17061706}
17071707/* }}} */
17081708
1709- /* {{{ Substitutes xincludes in a DomDocument */
1709+ static void dom_xinclude_strip_references (xmlNodePtr basep )
1710+ {
1711+ php_libxml_node_free_resource (basep );
1712+
1713+ xmlNodePtr current = basep -> children ;
1714+
1715+ while (current ) {
1716+ php_libxml_node_free_resource (current );
1717+ current = php_dom_next_in_tree_order (current , basep );
1718+ }
1719+ }
1720+
1721+ /* See GH-14702.
1722+ * We have to remove userland references to xinclude fallback nodes because libxml2 will make clones of these
1723+ * and remove the original nodes. If the originals are removed while there are still userland references
1724+ * this will cause memory corruption. */
1725+ static void dom_xinclude_strip_fallback_references (const xmlNode * basep )
1726+ {
1727+ xmlNodePtr current = basep -> children ;
1728+
1729+ while (current ) {
1730+ if (current -> type == XML_ELEMENT_NODE && current -> ns != NULL && current -> _private != NULL
1731+ && xmlStrEqual (current -> name , XINCLUDE_FALLBACK )
1732+ && (xmlStrEqual (current -> ns -> href , XINCLUDE_NS ) || xmlStrEqual (current -> ns -> href , XINCLUDE_OLD_NS ))) {
1733+ dom_xinclude_strip_references (current );
1734+ }
1735+
1736+ current = php_dom_next_in_tree_order (current , basep );
1737+ }
1738+ }
1739+
17101740static int dom_perform_xinclude (xmlDocPtr docp , dom_object * intern , zend_long flags )
17111741{
1742+ dom_xinclude_strip_fallback_references ((const xmlNode * ) docp );
1743+
17121744 PHP_LIBXML_SANITIZE_GLOBALS (xinclude );
17131745 int err = xmlXIncludeProcessFlags (docp , (int )flags );
17141746 PHP_LIBXML_RESTORE_GLOBALS (xinclude );
@@ -1730,6 +1762,7 @@ static int dom_perform_xinclude(xmlDocPtr docp, dom_object *intern, zend_long fl
17301762 return err ;
17311763}
17321764
1765+ /* {{{ Substitutues xincludes in a DomDocument */
17331766PHP_METHOD (DOMDocument , xinclude )
17341767{
17351768 xmlDoc * docp ;
0 commit comments