@@ -820,25 +820,56 @@ int dom_node_text_content_write(dom_object *obj, zval *newval)
820820
821821/* }}} */
822822
823- /* Returns true if the node was changed , false otherwise. */
824- static bool dom_set_document_ref_obj_single (xmlNodePtr node , xmlDocPtr doc , php_libxml_ref_obj * document )
823+ /* Returns true if the node had the same document reference , false otherwise. */
824+ static bool dom_set_document_ref_obj_single (xmlNodePtr node , php_libxml_ref_obj * document )
825825{
826826 dom_object * childobj = php_dom_object_get_data (node );
827- if (childobj && !childobj -> document ) {
827+ if (!childobj ) {
828+ return true;
829+ }
830+ if (!childobj -> document ) {
828831 childobj -> document = document ;
829832 document -> refcount ++ ;
830833 return true;
831834 }
832835 return false;
833836}
834837
838+ void dom_set_document_ref_pointers_attr (xmlAttrPtr attr , php_libxml_ref_obj * document )
839+ {
840+ ZEND_ASSERT (document != NULL );
841+
842+ dom_set_document_ref_obj_single ((xmlNodePtr ) attr , document );
843+ for (xmlNodePtr attr_child = attr -> children ; attr_child ; attr_child = attr_child -> next ) {
844+ dom_set_document_ref_obj_single (attr_child , document );
845+ }
846+ }
847+
848+ static bool dom_set_document_ref_pointers_node (xmlNodePtr node , php_libxml_ref_obj * document )
849+ {
850+ ZEND_ASSERT (document != NULL );
851+
852+ if (!dom_set_document_ref_obj_single (node , document )) {
853+ return false;
854+ }
855+
856+ if (node -> type == XML_ELEMENT_NODE ) {
857+ for (xmlAttrPtr attr = node -> properties ; attr ; attr = attr -> next ) {
858+ dom_set_document_ref_pointers_attr (attr , document );
859+ }
860+ }
861+
862+ return true;
863+ }
864+
835865/* TODO: on 8.4 replace the loop with the tree walk helper function. */
836- static void dom_set_document_pointers (xmlNodePtr node , xmlDocPtr doc , php_libxml_ref_obj * document )
866+ void dom_set_document_ref_pointers (xmlNodePtr node , php_libxml_ref_obj * document )
837867{
838- /* Applies the document to the entire subtree. */
839- xmlSetTreeDoc (node , doc );
868+ if (!document ) {
869+ return ;
870+ }
840871
841- if (!dom_set_document_ref_obj_single (node , doc , document )) {
872+ if (!dom_set_document_ref_pointers_node (node , document )) {
842873 return ;
843874 }
844875
@@ -847,7 +878,7 @@ static void dom_set_document_pointers(xmlNodePtr node, xmlDocPtr doc, php_libxml
847878 while (node != NULL ) {
848879 ZEND_ASSERT (node != base );
849880
850- if (!dom_set_document_ref_obj_single (node , doc , document )) {
881+ if (!dom_set_document_ref_pointers_node (node , document )) {
851882 break ;
852883 }
853884
@@ -974,7 +1005,7 @@ PHP_METHOD(DOMNode, insertBefore)
9741005 }
9751006
9761007 if (child -> doc == NULL && parentp -> doc != NULL ) {
977- dom_set_document_pointers (child , parentp -> doc , intern -> document );
1008+ dom_set_document_ref_pointers (child , intern -> document );
9781009 }
9791010
9801011 php_libxml_invalidate_node_list_cache (intern -> document );
@@ -1137,7 +1168,7 @@ PHP_METHOD(DOMNode, replaceChild)
11371168 }
11381169
11391170 if (newchild -> doc == NULL && nodep -> doc != NULL ) {
1140- dom_set_document_pointers (newchild , nodep -> doc , intern -> document );
1171+ dom_set_document_ref_pointers (newchild , intern -> document );
11411172 }
11421173
11431174 if (newchild -> type == XML_DOCUMENT_FRAG_NODE ) {
@@ -1240,7 +1271,7 @@ PHP_METHOD(DOMNode, appendChild)
12401271 }
12411272
12421273 if (child -> doc == NULL && nodep -> doc != NULL ) {
1243- dom_set_document_pointers (child , nodep -> doc , intern -> document );
1274+ dom_set_document_ref_pointers (child , intern -> document );
12441275 }
12451276
12461277 if (child -> parent != NULL ){
0 commit comments