@@ -89,6 +89,7 @@ static HashTable dom_xpath_prop_handlers;
89
89
90
90
static zend_object * dom_objects_namespace_node_new (zend_class_entry * class_type );
91
91
static void dom_object_namespace_node_free_storage (zend_object * object );
92
+ static xmlNodePtr php_dom_create_fake_namespace_decl_node_ptr (xmlNodePtr nodep , xmlNsPtr original );
92
93
93
94
typedef int (* dom_read_t )(dom_object * obj , zval * retval );
94
95
typedef int (* dom_write_t )(dom_object * obj , zval * newval );
@@ -480,6 +481,19 @@ PHP_FUNCTION(dom_import_simplexml)
480
481
481
482
static dom_object * dom_objects_set_class (zend_class_entry * class_type );
482
483
484
+ static void dom_update_refcount_after_clone (dom_object * original , xmlNodePtr original_node , dom_object * clone , xmlNodePtr cloned_node )
485
+ {
486
+ /* If we cloned a document then we must create new doc proxy */
487
+ if (cloned_node -> doc == original_node -> doc ) {
488
+ clone -> document = original -> document ;
489
+ }
490
+ php_libxml_increment_doc_ref ((php_libxml_node_object * )clone , cloned_node -> doc );
491
+ php_libxml_increment_node_ptr ((php_libxml_node_object * )clone , cloned_node , (void * )clone );
492
+ if (original -> document != clone -> document ) {
493
+ dom_copy_doc_props (original -> document , clone -> document );
494
+ }
495
+ }
496
+
483
497
static zend_object * dom_objects_store_clone_obj (zend_object * zobject ) /* {{{ */
484
498
{
485
499
dom_object * intern = php_dom_obj_from_obj (zobject );
@@ -492,15 +506,7 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
492
506
if (node != NULL ) {
493
507
xmlNodePtr cloned_node = xmlDocCopyNode (node , node -> doc , 1 );
494
508
if (cloned_node != NULL ) {
495
- /* If we cloned a document then we must create new doc proxy */
496
- if (cloned_node -> doc == node -> doc ) {
497
- clone -> document = intern -> document ;
498
- }
499
- php_libxml_increment_doc_ref ((php_libxml_node_object * )clone , cloned_node -> doc );
500
- php_libxml_increment_node_ptr ((php_libxml_node_object * )clone , cloned_node , (void * )clone );
501
- if (intern -> document != clone -> document ) {
502
- dom_copy_doc_props (intern -> document , clone -> document );
503
- }
509
+ dom_update_refcount_after_clone (intern , node , clone , cloned_node );
504
510
}
505
511
506
512
}
@@ -512,6 +518,26 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
512
518
}
513
519
/* }}} */
514
520
521
+ static zend_object * dom_object_namespace_node_clone_obj (zend_object * zobject )
522
+ {
523
+ dom_object_namespace_node * intern = php_dom_namespace_node_obj_from_obj (zobject );
524
+ zend_object * clone = dom_objects_namespace_node_new (intern -> dom .std .ce );
525
+ dom_object_namespace_node * clone_intern = php_dom_namespace_node_obj_from_obj (clone );
526
+
527
+ xmlNodePtr original_node = dom_object_get_node (& intern -> dom );
528
+ ZEND_ASSERT (original_node -> type == XML_NAMESPACE_DECL );
529
+ xmlNodePtr cloned_node = php_dom_create_fake_namespace_decl_node_ptr (original_node -> parent , original_node -> ns );
530
+
531
+ if (intern -> parent_intern ) {
532
+ clone_intern -> parent_intern = intern -> parent_intern ;
533
+ GC_ADDREF (& clone_intern -> parent_intern -> std );
534
+ }
535
+ dom_update_refcount_after_clone (& intern -> dom , original_node , & clone_intern -> dom , cloned_node );
536
+
537
+ zend_objects_clone_members (clone , & intern -> dom .std );
538
+ return clone ;
539
+ }
540
+
515
541
static void dom_copy_prop_handler (zval * zv ) /* {{{ */
516
542
{
517
543
dom_prop_handler * hnd = Z_PTR_P (zv );
@@ -580,6 +606,7 @@ PHP_MINIT_FUNCTION(dom)
580
606
memcpy (& dom_object_namespace_node_handlers , & dom_object_handlers , sizeof (zend_object_handlers ));
581
607
dom_object_namespace_node_handlers .offset = XtOffsetOf (dom_object_namespace_node , dom .std );
582
608
dom_object_namespace_node_handlers .free_obj = dom_object_namespace_node_free_storage ;
609
+ dom_object_namespace_node_handlers .clone_obj = dom_object_namespace_node_clone_obj ;
583
610
584
611
zend_hash_init (& classes , 0 , NULL , NULL , 1 );
585
612
@@ -1608,8 +1635,7 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
1608
1635
}
1609
1636
/* }}} end dom_get_nsdecl */
1610
1637
1611
- /* Note: Assumes the additional lifetime was already added in the caller. */
1612
- xmlNodePtr php_dom_create_fake_namespace_decl (xmlNodePtr nodep , xmlNsPtr original , zval * return_value , dom_object * parent_intern )
1638
+ static xmlNodePtr php_dom_create_fake_namespace_decl_node_ptr (xmlNodePtr nodep , xmlNsPtr original )
1613
1639
{
1614
1640
xmlNodePtr attrp ;
1615
1641
xmlNsPtr curns = xmlNewNs (NULL , original -> href , NULL );
@@ -1622,11 +1648,16 @@ xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr origina
1622
1648
attrp -> type = XML_NAMESPACE_DECL ;
1623
1649
attrp -> parent = nodep ;
1624
1650
attrp -> ns = curns ;
1651
+ return attrp ;
1652
+ }
1625
1653
1654
+ /* Note: Assumes the additional lifetime was already added in the caller. */
1655
+ xmlNodePtr php_dom_create_fake_namespace_decl (xmlNodePtr nodep , xmlNsPtr original , zval * return_value , dom_object * parent_intern )
1656
+ {
1657
+ xmlNodePtr attrp = php_dom_create_fake_namespace_decl_node_ptr (nodep , original );
1626
1658
php_dom_create_object (attrp , return_value , parent_intern );
1627
1659
/* This object must exist, because we just created an object for it via php_dom_create_object(). */
1628
- dom_object * obj = ((php_libxml_node_ptr * )attrp -> _private )-> _private ;
1629
- php_dom_namespace_node_obj_from_obj (& obj -> std )-> parent_intern = parent_intern ;
1660
+ php_dom_namespace_node_obj_from_obj (Z_OBJ_P (return_value ))-> parent_intern = parent_intern ;
1630
1661
return attrp ;
1631
1662
}
1632
1663
0 commit comments