@@ -61,6 +61,7 @@ PHP_DOM_EXPORT zend_class_entry *dom_namespace_node_class_entry;
6161
6262zend_object_handlers dom_object_handlers ;
6363zend_object_handlers dom_nnodemap_object_handlers ;
64+ zend_object_handlers dom_object_namespace_node_handlers ;
6465#ifdef LIBXML_XPATH_ENABLED
6566zend_object_handlers dom_xpath_object_handlers ;
6667#endif
@@ -86,6 +87,9 @@ static HashTable dom_xpath_prop_handlers;
8687#endif
8788/* }}} */
8889
90+ static zend_object * dom_objects_namespace_node_new (zend_class_entry * class_type );
91+ static void dom_object_namespace_node_free_storage (zend_object * object );
92+
8993typedef int (* dom_read_t )(dom_object * obj , zval * retval );
9094typedef int (* dom_write_t )(dom_object * obj , zval * newval );
9195
@@ -570,6 +574,10 @@ PHP_MINIT_FUNCTION(dom)
570574 dom_nnodemap_object_handlers .read_dimension = dom_nodelist_read_dimension ;
571575 dom_nnodemap_object_handlers .has_dimension = dom_nodelist_has_dimension ;
572576
577+ memcpy (& dom_object_namespace_node_handlers , & dom_object_handlers , sizeof (zend_object_handlers ));
578+ dom_object_namespace_node_handlers .offset = XtOffsetOf (dom_object_namespace_node , dom .std );
579+ dom_object_namespace_node_handlers .free_obj = dom_object_namespace_node_free_storage ;
580+
573581 zend_hash_init (& classes , 0 , NULL , NULL , 1 );
574582
575583 dom_domexception_class_entry = register_class_DOMException (zend_ce_exception );
@@ -604,7 +612,7 @@ PHP_MINIT_FUNCTION(dom)
604612 zend_hash_add_ptr (& classes , dom_node_class_entry -> name , & dom_node_prop_handlers );
605613
606614 dom_namespace_node_class_entry = register_class_DOMNameSpaceNode ();
607- dom_namespace_node_class_entry -> create_object = dom_objects_new ;
615+ dom_namespace_node_class_entry -> create_object = dom_objects_namespace_node_new ;
608616
609617 zend_hash_init (& dom_namespace_node_prop_handlers , 0 , NULL , dom_dtor_prop_handler , 1 );
610618 dom_register_prop_handler (& dom_namespace_node_prop_handlers , "nodeName" , sizeof ("nodeName" )- 1 , dom_node_node_name_read , NULL );
@@ -1001,10 +1009,8 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml
10011009}
10021010/* }}} */
10031011
1004- static dom_object * dom_objects_set_class (zend_class_entry * class_type ) /* {{{ */
1012+ static void dom_objects_set_class_ex (zend_class_entry * class_type , dom_object * intern )
10051013{
1006- dom_object * intern = zend_object_alloc (sizeof (dom_object ), class_type );
1007-
10081014 zend_class_entry * base_class = class_type ;
10091015 while ((base_class -> type != ZEND_INTERNAL_CLASS || base_class -> info .internal .module -> module_number != dom_module_entry .module_number ) && base_class -> parent != NULL ) {
10101016 base_class = base_class -> parent ;
@@ -1014,10 +1020,14 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type) /* {{{ */
10141020
10151021 zend_object_std_init (& intern -> std , class_type );
10161022 object_properties_init (& intern -> std , class_type );
1023+ }
10171024
1025+ static dom_object * dom_objects_set_class (zend_class_entry * class_type )
1026+ {
1027+ dom_object * intern = zend_object_alloc (sizeof (dom_object ), class_type );
1028+ dom_objects_set_class_ex (class_type , intern );
10181029 return intern ;
10191030}
1020- /* }}} */
10211031
10221032/* {{{ dom_objects_new */
10231033zend_object * dom_objects_new (zend_class_entry * class_type )
@@ -1028,6 +1038,25 @@ zend_object *dom_objects_new(zend_class_entry *class_type)
10281038}
10291039/* }}} */
10301040
1041+ static zend_object * dom_objects_namespace_node_new (zend_class_entry * class_type )
1042+ {
1043+ dom_object_namespace_node * intern = zend_object_alloc (sizeof (dom_object_namespace_node ), class_type );
1044+ dom_objects_set_class_ex (class_type , & intern -> dom );
1045+ intern -> dom .std .handlers = & dom_object_namespace_node_handlers ;
1046+ return & intern -> dom .std ;
1047+ }
1048+
1049+ static void dom_object_namespace_node_free_storage (zend_object * object )
1050+ {
1051+ dom_object_namespace_node * intern = php_dom_namespace_node_obj_from_obj (object );
1052+ if (intern -> parent_intern != NULL ) {
1053+ zval tmp ;
1054+ ZVAL_OBJ (& tmp , & intern -> parent_intern -> std );
1055+ zval_ptr_dtor (& tmp );
1056+ }
1057+ dom_objects_free_storage (object );
1058+ }
1059+
10311060#ifdef LIBXML_XPATH_ENABLED
10321061/* {{{ zend_object dom_xpath_objects_new(zend_class_entry *class_type) */
10331062zend_object * dom_xpath_objects_new (zend_class_entry * class_type )
@@ -1550,6 +1579,28 @@ xmlNsPtr dom_get_nsdecl(xmlNode *node, xmlChar *localName) {
15501579}
15511580/* }}} end dom_get_nsdecl */
15521581
1582+ /* Note: Assumes the additional lifetime was already added in the caller. */
1583+ xmlNodePtr php_dom_create_fake_namespace_decl (xmlNodePtr nodep , xmlNsPtr original , zval * return_value , dom_object * parent_intern )
1584+ {
1585+ xmlNodePtr attrp ;
1586+ xmlNsPtr curns = xmlNewNs (NULL , original -> href , NULL );
1587+ if (original -> prefix ) {
1588+ curns -> prefix = xmlStrdup (original -> prefix );
1589+ attrp = xmlNewDocNode (nodep -> doc , NULL , (xmlChar * ) original -> prefix , original -> href );
1590+ } else {
1591+ attrp = xmlNewDocNode (nodep -> doc , NULL , (xmlChar * )"xmlns" , original -> href );
1592+ }
1593+ attrp -> type = XML_NAMESPACE_DECL ;
1594+ attrp -> parent = nodep ;
1595+ attrp -> ns = curns ;
1596+
1597+ php_dom_create_object (attrp , return_value , parent_intern );
1598+ /* This object must exist, because we just created an object for it via php_dom_create_object(). */
1599+ dom_object * obj = ((php_libxml_node_ptr * )attrp -> _private )-> _private ;
1600+ php_dom_namespace_node_obj_from_obj (& obj -> std )-> parent_intern = parent_intern ;
1601+ return attrp ;
1602+ }
1603+
15531604static zval * dom_nodelist_read_dimension (zend_object * object , zval * offset , int type , zval * rv ) /* {{{ */
15541605{
15551606 zval offset_copy ;
0 commit comments