@@ -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 );
@@ -477,6 +478,19 @@ PHP_FUNCTION(dom_import_simplexml)
477
478
478
479
static dom_object * dom_objects_set_class (zend_class_entry * class_type );
479
480
481
+ static void dom_update_refcount_after_clone (dom_object * original , xmlNodePtr original_node , dom_object * clone , xmlNodePtr cloned_node )
482
+ {
483
+ /* If we cloned a document then we must create new doc proxy */
484
+ if (cloned_node -> doc == original_node -> doc ) {
485
+ clone -> document = original -> document ;
486
+ }
487
+ php_libxml_increment_doc_ref ((php_libxml_node_object * )clone , cloned_node -> doc );
488
+ php_libxml_increment_node_ptr ((php_libxml_node_object * )clone , cloned_node , (void * )clone );
489
+ if (original -> document != clone -> document ) {
490
+ dom_copy_doc_props (original -> document , clone -> document );
491
+ }
492
+ }
493
+
480
494
static zend_object * dom_objects_store_clone_obj (zend_object * zobject ) /* {{{ */
481
495
{
482
496
dom_object * intern = php_dom_obj_from_obj (zobject );
@@ -489,15 +503,7 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
489
503
if (node != NULL ) {
490
504
xmlNodePtr cloned_node = xmlDocCopyNode (node , node -> doc , 1 );
491
505
if (cloned_node != NULL ) {
492
- /* If we cloned a document then we must create new doc proxy */
493
- if (cloned_node -> doc == node -> doc ) {
494
- clone -> document = intern -> document ;
495
- }
496
- php_libxml_increment_doc_ref ((php_libxml_node_object * )clone , cloned_node -> doc );
497
- php_libxml_increment_node_ptr ((php_libxml_node_object * )clone , cloned_node , (void * )clone );
498
- if (intern -> document != clone -> document ) {
499
- dom_copy_doc_props (intern -> document , clone -> document );
500
- }
506
+ dom_update_refcount_after_clone (intern , node , clone , cloned_node );
501
507
}
502
508
503
509
}
@@ -509,6 +515,26 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
509
515
}
510
516
/* }}} */
511
517
518
+ static zend_object * dom_object_namespace_node_clone_obj (zend_object * zobject )
519
+ {
520
+ dom_object_namespace_node * intern = php_dom_namespace_node_obj_from_obj (zobject );
521
+ zend_object * clone = dom_objects_namespace_node_new (intern -> dom .std .ce );
522
+ dom_object_namespace_node * clone_intern = php_dom_namespace_node_obj_from_obj (clone );
523
+
524
+ xmlNodePtr original_node = dom_object_get_node (& intern -> dom );
525
+ ZEND_ASSERT (original_node -> type == XML_NAMESPACE_DECL );
526
+ xmlNodePtr cloned_node = php_dom_create_fake_namespace_decl_node_ptr (original_node -> parent , original_node -> ns );
527
+
528
+ if (intern -> parent_intern ) {
529
+ clone_intern -> parent_intern = intern -> parent_intern ;
530
+ GC_ADDREF (& clone_intern -> parent_intern -> std );
531
+ }
532
+ dom_update_refcount_after_clone (& intern -> dom , original_node , & clone_intern -> dom , cloned_node );
533
+
534
+ zend_objects_clone_members (clone , & intern -> dom .std );
535
+ return clone ;
536
+ }
537
+
512
538
static void dom_copy_prop_handler (zval * zv ) /* {{{ */
513
539
{
514
540
dom_prop_handler * hnd = Z_PTR_P (zv );
@@ -577,6 +603,7 @@ PHP_MINIT_FUNCTION(dom)
577
603
memcpy (& dom_object_namespace_node_handlers , & dom_object_handlers , sizeof (zend_object_handlers ));
578
604
dom_object_namespace_node_handlers .offset = XtOffsetOf (dom_object_namespace_node , dom .std );
579
605
dom_object_namespace_node_handlers .free_obj = dom_object_namespace_node_free_storage ;
606
+ dom_object_namespace_node_handlers .clone_obj = dom_object_namespace_node_clone_obj ;
580
607
581
608
zend_hash_init (& classes , 0 , NULL , NULL , 1 );
582
609
@@ -1530,8 +1557,7 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
1530
1557
}
1531
1558
/* }}} end dom_get_nsdecl */
1532
1559
1533
- /* Note: Assumes the additional lifetime was already added in the caller. */
1534
- xmlNodePtr php_dom_create_fake_namespace_decl (xmlNodePtr nodep , xmlNsPtr original , zval * return_value , dom_object * parent_intern )
1560
+ static xmlNodePtr php_dom_create_fake_namespace_decl_node_ptr (xmlNodePtr nodep , xmlNsPtr original )
1535
1561
{
1536
1562
xmlNodePtr attrp ;
1537
1563
xmlNsPtr curns = xmlNewNs (NULL , original -> href , NULL );
@@ -1544,11 +1570,16 @@ xmlNodePtr php_dom_create_fake_namespace_decl(xmlNodePtr nodep, xmlNsPtr origina
1544
1570
attrp -> type = XML_NAMESPACE_DECL ;
1545
1571
attrp -> parent = nodep ;
1546
1572
attrp -> ns = curns ;
1573
+ return attrp ;
1574
+ }
1547
1575
1576
+ /* Note: Assumes the additional lifetime was already added in the caller. */
1577
+ xmlNodePtr php_dom_create_fake_namespace_decl (xmlNodePtr nodep , xmlNsPtr original , zval * return_value , dom_object * parent_intern )
1578
+ {
1579
+ xmlNodePtr attrp = php_dom_create_fake_namespace_decl_node_ptr (nodep , original );
1548
1580
php_dom_create_object (attrp , return_value , parent_intern );
1549
1581
/* This object must exist, because we just created an object for it via php_dom_create_object(). */
1550
- dom_object * obj = ((php_libxml_node_ptr * )attrp -> _private )-> _private ;
1551
- php_dom_namespace_node_obj_from_obj (& obj -> std )-> parent_intern = parent_intern ;
1582
+ php_dom_namespace_node_obj_from_obj (Z_OBJ_P (return_value ))-> parent_intern = parent_intern ;
1552
1583
return attrp ;
1553
1584
}
1554
1585
0 commit comments