@@ -740,36 +740,61 @@ zend_result dom_node_text_content_write(dom_object *obj, zval *newval)
740740
741741/* }}} */
742742
743- /* Returns true if the node was changed , false otherwise. */
744- static bool dom_set_document_ref_obj_single (xmlNodePtr node , xmlDocPtr doc , php_libxml_ref_obj * document )
743+ /* Returns true if the node had the same document reference , false otherwise. */
744+ static bool dom_set_document_ref_obj_single (xmlNodePtr node , php_libxml_ref_obj * document )
745745{
746746 dom_object * childobj = php_dom_object_get_data (node );
747- if (childobj && !childobj -> document ) {
747+ if (!childobj ) {
748+ return true;
749+ }
750+ if (!childobj -> document ) {
748751 childobj -> document = document ;
749752 document -> refcount ++ ;
750753 return true;
751754 }
752755 return false;
753756}
754757
755- static void dom_set_document_pointers ( xmlNodePtr node , xmlDocPtr doc , php_libxml_ref_obj * document )
758+ void dom_set_document_ref_pointers_attr ( xmlAttrPtr attr , php_libxml_ref_obj * document )
756759{
757- /* Applies the document to the entire subtree. */
758- xmlSetTreeDoc (node , doc );
760+ ZEND_ASSERT (document != NULL );
759761
760- if (!dom_set_document_ref_obj_single (node , doc , document )) {
761- return ;
762+ dom_set_document_ref_obj_single ((xmlNodePtr ) attr , document );
763+ for (xmlNodePtr attr_child = attr -> children ; attr_child ; attr_child = attr_child -> next ) {
764+ dom_set_document_ref_obj_single (attr_child , document );
762765 }
766+ }
763767
764- xmlNodePtr base = node ;
765- node = node -> children ;
766- while (node != NULL ) {
767- ZEND_ASSERT (node != base );
768+ static bool dom_set_document_ref_pointers_node (xmlNodePtr node , php_libxml_ref_obj * document )
769+ {
770+ ZEND_ASSERT (document != NULL );
768771
769- if (!dom_set_document_ref_obj_single (node , doc , document )) {
770- break ;
772+ if (!dom_set_document_ref_obj_single (node , document )) {
773+ return false;
774+ }
775+
776+ if (node -> type == XML_ELEMENT_NODE ) {
777+ for (xmlAttrPtr attr = node -> properties ; attr ; attr = attr -> next ) {
778+ dom_set_document_ref_pointers_attr (attr , document );
771779 }
780+ }
781+
782+ return true;
783+ }
772784
785+ void dom_set_document_ref_pointers (xmlNodePtr node , php_libxml_ref_obj * document )
786+ {
787+ if (!document ) {
788+ return ;
789+ }
790+
791+ if (!dom_set_document_ref_pointers_node (node , document )) {
792+ return ;
793+ }
794+
795+ xmlNodePtr base = node ;
796+ node = node -> children ;
797+ while (node != NULL && dom_set_document_ref_pointers_node (node , document )) {
773798 node = php_dom_next_in_tree_order (node , base );
774799 }
775800}
@@ -860,7 +885,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
860885 }
861886
862887 if (child -> doc == NULL && parentp -> doc != NULL ) {
863- dom_set_document_pointers (child , parentp -> doc , intern -> document );
888+ dom_set_document_ref_pointers (child , intern -> document );
864889 }
865890
866891 php_libxml_invalidate_node_list_cache (intern -> document );
@@ -1167,7 +1192,7 @@ static void dom_node_replace_child(INTERNAL_FUNCTION_PARAMETERS, bool modern)
11671192 }
11681193
11691194 if (newchild -> doc == NULL && nodep -> doc != NULL ) {
1170- dom_set_document_pointers (newchild , nodep -> doc , intern -> document );
1195+ dom_set_document_ref_pointers (newchild , intern -> document );
11711196 }
11721197
11731198 if (newchild -> type == XML_DOCUMENT_FRAG_NODE ) {
@@ -1275,7 +1300,7 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern,
12751300 }
12761301
12771302 if (child -> doc == NULL && nodep -> doc != NULL ) {
1278- dom_set_document_pointers (child , nodep -> doc , intern -> document );
1303+ dom_set_document_ref_pointers (child , intern -> document );
12791304 }
12801305
12811306 if (child -> parent != NULL ){
0 commit comments