@@ -740,11 +740,43 @@ zend_result dom_node_text_content_write(dom_object *obj, zval *newval)
740
740
741
741
/* }}} */
742
742
743
- static xmlNodePtr dom_insert_fragment (xmlNodePtr nodep , xmlNodePtr prevsib , xmlNodePtr nextsib , xmlNodePtr fragment , dom_object * intern ) /* {{{ */
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 )
744
745
{
745
- xmlNodePtr newchild , node ;
746
+ dom_object * childobj = php_dom_object_get_data (node );
747
+ if (childobj && !childobj -> document ) {
748
+ childobj -> document = document ;
749
+ document -> refcount ++ ;
750
+ return true;
751
+ }
752
+ return false;
753
+ }
754
+
755
+ static void dom_set_document_pointers (xmlNodePtr node , xmlDocPtr doc , php_libxml_ref_obj * document )
756
+ {
757
+ /* Applies the document to the entire subtree. */
758
+ xmlSetTreeDoc (node , doc );
759
+
760
+ if (!dom_set_document_ref_obj_single (node , doc , document )) {
761
+ return ;
762
+ }
763
+
764
+ xmlNodePtr base = node ;
765
+ node = node -> children ;
766
+ while (node != NULL ) {
767
+ ZEND_ASSERT (node != base );
768
+
769
+ if (!dom_set_document_ref_obj_single (node , doc , document )) {
770
+ break ;
771
+ }
746
772
747
- newchild = fragment -> children ;
773
+ node = php_dom_next_in_tree_order (node , base );
774
+ }
775
+ }
776
+
777
+ static xmlNodePtr dom_insert_fragment (xmlNodePtr nodep , xmlNodePtr prevsib , xmlNodePtr nextsib , xmlNodePtr fragment , dom_object * intern ) /* {{{ */
778
+ {
779
+ xmlNodePtr newchild = fragment -> children ;
748
780
749
781
if (newchild ) {
750
782
if (prevsib == NULL ) {
@@ -760,17 +792,10 @@ static xmlNodePtr dom_insert_fragment(xmlNodePtr nodep, xmlNodePtr prevsib, xmlN
760
792
nextsib -> prev = fragment -> last ;
761
793
}
762
794
763
- node = newchild ;
795
+ /* Assign parent node pointer */
796
+ xmlNodePtr node = newchild ;
764
797
while (node != NULL ) {
765
798
node -> parent = nodep ;
766
- if (node -> doc != nodep -> doc ) {
767
- xmlSetTreeDoc (node , nodep -> doc );
768
- dom_object * childobj = node -> _private ;
769
- if (childobj != NULL ) {
770
- childobj -> document = intern -> document ;
771
- php_libxml_increment_doc_ref ((php_libxml_node_object * )childobj , NULL );
772
- }
773
- }
774
799
if (node == fragment -> last ) {
775
800
break ;
776
801
}
@@ -835,8 +860,7 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
835
860
}
836
861
837
862
if (child -> doc == NULL && parentp -> doc != NULL ) {
838
- childobj -> document = intern -> document ;
839
- php_libxml_increment_doc_ref ((php_libxml_node_object * )childobj , NULL );
863
+ dom_set_document_pointers (child , parentp -> doc , intern -> document );
840
864
}
841
865
842
866
php_libxml_invalidate_node_list_cache (intern -> document );
@@ -856,9 +880,6 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
856
880
857
881
if (child -> type == XML_TEXT_NODE && (refp -> type == XML_TEXT_NODE ||
858
882
(refp -> prev != NULL && refp -> prev -> type == XML_TEXT_NODE ))) {
859
- if (child -> doc == NULL ) {
860
- xmlSetTreeDoc (child , parentp -> doc );
861
- }
862
883
new_child = child ;
863
884
new_child -> parent = refp -> parent ;
864
885
new_child -> next = refp ;
@@ -910,9 +931,6 @@ static void dom_node_insert_before_legacy(zval *return_value, zval *ref, dom_obj
910
931
}
911
932
if (child -> type == XML_TEXT_NODE && parentp -> last != NULL && parentp -> last -> type == XML_TEXT_NODE ) {
912
933
child -> parent = parentp ;
913
- if (child -> doc == NULL ) {
914
- xmlSetTreeDoc (child , parentp -> doc );
915
- }
916
934
new_child = child ;
917
935
if (parentp -> children == NULL ) {
918
936
parentp -> children = child ;
@@ -1155,6 +1173,10 @@ static void dom_node_replace_child(INTERNAL_FUNCTION_PARAMETERS, bool modern)
1155
1173
}
1156
1174
}
1157
1175
1176
+ if (newchild -> doc == NULL && nodep -> doc != NULL ) {
1177
+ dom_set_document_pointers (newchild , nodep -> doc , intern -> document );
1178
+ }
1179
+
1158
1180
if (newchild -> type == XML_DOCUMENT_FRAG_NODE ) {
1159
1181
xmlNodePtr prevsib , nextsib ;
1160
1182
prevsib = oldchild -> prev ;
@@ -1171,11 +1193,6 @@ static void dom_node_replace_child(INTERNAL_FUNCTION_PARAMETERS, bool modern)
1171
1193
xmlDtdPtr intSubset = xmlGetIntSubset (nodep -> doc );
1172
1194
bool replacedoctype = (intSubset == (xmlDtd * ) oldchild );
1173
1195
1174
- if (newchild -> doc == NULL && nodep -> doc != NULL ) {
1175
- xmlSetTreeDoc (newchild , nodep -> doc );
1176
- newchildobj -> document = intern -> document ;
1177
- php_libxml_increment_doc_ref ((php_libxml_node_object * )newchildobj , NULL );
1178
- }
1179
1196
xmlReplaceNode (oldchild , newchild );
1180
1197
if (!modern ) {
1181
1198
dom_reconcile_ns (nodep -> doc , newchild );
@@ -1265,8 +1282,7 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern,
1265
1282
}
1266
1283
1267
1284
if (child -> doc == NULL && nodep -> doc != NULL ) {
1268
- childobj -> document = intern -> document ;
1269
- php_libxml_increment_doc_ref ((php_libxml_node_object * )childobj , NULL );
1285
+ dom_set_document_pointers (child , nodep -> doc , intern -> document );
1270
1286
}
1271
1287
1272
1288
if (child -> parent != NULL ){
@@ -1275,9 +1291,6 @@ static void dom_node_append_child_legacy(zval *return_value, dom_object *intern,
1275
1291
1276
1292
if (child -> type == XML_TEXT_NODE && nodep -> last != NULL && nodep -> last -> type == XML_TEXT_NODE ) {
1277
1293
child -> parent = nodep ;
1278
- if (child -> doc == NULL ) {
1279
- xmlSetTreeDoc (child , nodep -> doc );
1280
- }
1281
1294
new_child = child ;
1282
1295
if (nodep -> children == NULL ) {
1283
1296
nodep -> children = child ;
0 commit comments