]> granicus.if.org Git - php/commitdiff
implement clone functionality to fix segfault
authorRob Richards <rrichards@php.net>
Tue, 17 Feb 2004 11:13:47 +0000 (11:13 +0000)
committerRob Richards <rrichards@php.net>
Tue, 17 Feb 2004 11:13:47 +0000 (11:13 +0000)
DomNode->clone() creates new doc proxy if document is cloned
remove printf from xpath
fix remaining invalid object state issues

ext/dom/dom_iterators.c
ext/dom/namednodemap.c
ext/dom/node.c
ext/dom/nodelist.c
ext/dom/php_dom.c
ext/dom/xpath.c

index 6e027c243e567856bfef22c9b922271720405cf9..78c2492312708f95bc72732fd1b5bff3ff32d5bc 100644 (file)
@@ -268,33 +268,35 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TS
 
        intern = (dom_object *)zend_object_store_get_object(object TSRMLS_CC);
        objmap = (dom_nnodemap_object *)intern->ptr;
-       if (objmap->ht == NULL) {
-               if (objmap->nodetype == DOM_NODESET) {
-                       nodeht = HASH_OF(objmap->baseobjptr);
-                       zend_hash_internal_pointer_reset(nodeht);
-                       if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
-                               curattr = *entry;
-                               curattr->refcount++;
-                       }
-               } else {
-                       nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
-                       if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
-                               if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
-                                       curnode = (xmlNodePtr) nodep->properties;
-                               } else {
-                                       curnode = (xmlNodePtr) nodep->children;
+       if (objmap != NULL) {
+               if (objmap->ht == NULL) {
+                       if (objmap->nodetype == DOM_NODESET) {
+                               nodeht = HASH_OF(objmap->baseobjptr);
+                               zend_hash_internal_pointer_reset(nodeht);
+                               if (zend_hash_get_current_data(nodeht, (void **) &entry)==SUCCESS) {
+                                       curattr = *entry;
+                                       curattr->refcount++;
                                }
                        } else {
-                               if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
-                                       nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                               nodep = (xmlNode *)dom_object_get_node(objmap->baseobj);
+                               if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                                       if (objmap->nodetype == XML_ATTRIBUTE_NODE) {
+                                               curnode = (xmlNodePtr) nodep->properties;
+                                       } else {
+                                               curnode = (xmlNodePtr) nodep->children;
+                                       }
                                } else {
-                                       nodep = nodep->children;
+                                       if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                                               nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                                       } else {
+                                               nodep = nodep->children;
+                                       }
+                                       curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
                                }
-                               curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &curindex, 0);
                        }
+               } else {
+                       curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
                }
-       } else {
-               curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
        }
 
        if (curnode) {
index 877845fbcfe17db47d0e5705af6cf7225541a32d..7f7f3a544f2fc27955837d179a8e8307cf10f46b 100644 (file)
@@ -61,17 +61,20 @@ int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
        int count = 0;
 
        objmap = (dom_nnodemap_object *)obj->ptr;
-       if (objmap->ht) {
-               count = xmlHashSize(objmap->ht);
-       } else {
-               nodep = dom_object_get_node(objmap->baseobj);
-               if (nodep) {
-                       curnode = nodep->properties;
-                       if (curnode) {
-                               count++;
-                               while (curnode->next != NULL) {
+
+       if (objmap != NULL) {
+               if (objmap->ht) {
+                       count = xmlHashSize(objmap->ht);
+               } else {
+                       nodep = dom_object_get_node(objmap->baseobj);
+                       if (nodep) {
+                               curnode = nodep->properties;
+                               if (curnode) {
                                        count++;
-                                       curnode = curnode->next;
+                                       while (curnode->next != NULL) {
+                                               count++;
+                                               curnode = curnode->next;
+                                       }
                                }
                        }
                }
@@ -110,17 +113,20 @@ PHP_FUNCTION(dom_namednodemap_get_named_item)
        intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
 
        objmap = (dom_nnodemap_object *)intern->ptr;
-       if (objmap->ht) {
-               if (objmap->nodetype == XML_ENTITY_NODE) {
-                       itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+
+       if (objmap != NULL) {
+               if (objmap->ht) {
+                       if (objmap->nodetype == XML_ENTITY_NODE) {
+                               itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+                       } else {
+                               notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+                               itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+                       }
                } else {
-                       notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
-                       itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
-               }
-       } else {
-               nodep = dom_object_get_node(objmap->baseobj);
-               if (nodep) {
-                       itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
+                       nodep = dom_object_get_node(objmap->baseobj);
+                       if (nodep) {
+                               itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
+                       }
                }
        }
 
@@ -178,26 +184,27 @@ PHP_FUNCTION(dom_namednodemap_item)
                intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
 
                objmap = (dom_nnodemap_object *)intern->ptr;
-               if (objmap->ht) {
-                       if (objmap->nodetype == XML_ENTITY_NODE) {
-                               itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+
+               if (objmap != NULL) {
+                       if (objmap->ht) {
+                               if (objmap->nodetype == XML_ENTITY_NODE) {
+                                       itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+                               } else {
+                                       itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
+                               }
                        } else {
-                               itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
-                       }
-               } else {
-                       nodep = dom_object_get_node(objmap->baseobj);
-                       if (nodep) {
-                               curnode = (xmlNodePtr)nodep->properties;
-                               count = 0;
-                               while (count < index && curnode != NULL) {
-                                       count++;
-                                       curnode = (xmlNodePtr)curnode->next;
+                               nodep = dom_object_get_node(objmap->baseobj);
+                               if (nodep) {
+                                       curnode = (xmlNodePtr)nodep->properties;
+                                       count = 0;
+                                       while (count < index && curnode != NULL) {
+                                               count++;
+                                               curnode = (xmlNodePtr)curnode->next;
+                                       }
+                                       itemnode = curnode;
                                }
-                               itemnode = curnode;
                        }
                }
-       } else {
-               RETURN_NULL();
        }
 
        if (itemnode) {
@@ -232,17 +239,20 @@ PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
        intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
 
        objmap = (dom_nnodemap_object *)intern->ptr;
-       if (objmap->ht) {
-               if (objmap->nodetype == XML_ENTITY_NODE) {
-                       itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+
+       if (objmap != NULL) {
+               if (objmap->ht) {
+                       if (objmap->nodetype == XML_ENTITY_NODE) {
+                               itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
+                       } else {
+                               notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
+                               itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
+                       }
                } else {
-                       notep = (xmlNotation *)xmlHashLookup(objmap->ht, named);
-                       itemnode = create_notation(notep->name, notep->PublicID, notep->SystemID);
-               }
-       } else {
-               nodep = dom_object_get_node(objmap->baseobj);
-               if (nodep) {
-                       itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
+                       nodep = dom_object_get_node(objmap->baseobj);
+                       if (nodep) {
+                               itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
+                       }
                }
        }
 
index d6843364faef3b547924941135881e1bd5e221a6..d052952bfa0cb332f4a078b819d8a70a94360d90 100644 (file)
@@ -1291,9 +1291,13 @@ PHP_FUNCTION(dom_node_clone_node)
 
        node = xmlDocCopyNode(n, n->doc, recursive);
 
+       if (!node) {
+               RETURN_FALSE;
+       }
+
        /* When deep is false Element nodes still require the attributes 
        Following taken from libxml as xmlDocCopyNode doesnt do this */
-       if (node && n->type == XML_ELEMENT_NODE && recursive == 0) {
+       if (n->type == XML_ELEMENT_NODE && recursive == 0) {
                if (n->nsDef != NULL) {
                        node->nsDef = xmlCopyNamespaceList(n->nsDef);
                }
@@ -1319,8 +1323,9 @@ PHP_FUNCTION(dom_node_clone_node)
                }
        }
 
-       if (!node) {
-               RETURN_FALSE;
+       /* If document cloned we want a new document proxy */
+       if (node->doc != n->doc) {
+               intern = NULL;
        }
 
        DOM_RET_OBJ(rv, node, &ret, intern);
index 22083228040ff20f066be4ec933672461593ccd1..198d1cb8eb4e1920f1e68d869a9d1c98532e13ab 100644 (file)
@@ -55,31 +55,33 @@ int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
        HashTable *nodeht;
 
        objmap = (dom_nnodemap_object *)obj->ptr;
-       if (objmap->ht) {
-               count = xmlHashSize(objmap->ht);
-       } else {
-               if (objmap->nodetype == DOM_NODESET) {
-                       nodeht = HASH_OF(objmap->baseobjptr);
-                       count = zend_hash_num_elements(nodeht);
+       if (objmap != NULL) {
+               if (objmap->ht) {
+                       count = xmlHashSize(objmap->ht);
                } else {
-                       nodep = dom_object_get_node(objmap->baseobj);
-                       if (nodep) {
-                               if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
-                                       curnode = nodep->children;
-                                       if (curnode) {
-                                               count++;
-                                               while (curnode->next != NULL) {
+                       if (objmap->nodetype == DOM_NODESET) {
+                               nodeht = HASH_OF(objmap->baseobjptr);
+                               count = zend_hash_num_elements(nodeht);
+                       } else {
+                               nodep = dom_object_get_node(objmap->baseobj);
+                               if (nodep) {
+                                       if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                                               curnode = nodep->children;
+                                               if (curnode) {
                                                        count++;
-                                                       curnode = curnode->next;
+                                                       while (curnode->next != NULL) {
+                                                               count++;
+                                                               curnode = curnode->next;
+                                                       }
                                                }
-                                       }
-                               } else {
-                                       if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
-                                               nodep = xmlDocGetRootElement((xmlDoc *) nodep);
                                        } else {
-                                               nodep = nodep->children;
+                                               if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                                                       nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                                               } else {
+                                                       nodep = nodep->children;
+                                               }
+                                               curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
                                        }
-                                       curnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, -1);
                                }
                        }
                }
@@ -118,43 +120,43 @@ PHP_FUNCTION(dom_nodelist_item)
                intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
 
                objmap = (dom_nnodemap_object *)intern->ptr;
-               if (objmap->ht) {
-                       if (objmap->nodetype == XML_ENTITY_NODE) {
-                               itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
-                       } else {
-                               itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
-                       }
-               } else {
-                       if (objmap->nodetype == DOM_NODESET) {
-                               nodeht = HASH_OF(objmap->baseobjptr);
-                               if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
-                                       *return_value = **entry;
-                                       zval_copy_ctor(return_value);
-                                       return;
+               if (objmap != NULL) {
+                       if (objmap->ht) {
+                               if (objmap->nodetype == XML_ENTITY_NODE) {
+                                       itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
+                               } else {
+                                       itemnode = php_dom_libxml_notation_iter(objmap->ht, index);
                                }
                        } else {
-                               nodep = dom_object_get_node(objmap->baseobj);
-                               if (nodep) {
-                                       if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
-                                               curnode = nodep->children;
-                                               while (count < index && curnode != NULL) {
-                                                       count++;
-                                                       curnode = curnode->next;
-                                               }
-                                               itemnode = curnode;
-                                       } else {
-                                               if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
-                                                       nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                               if (objmap->nodetype == DOM_NODESET) {
+                                       nodeht = HASH_OF(objmap->baseobjptr);
+                                       if (zend_hash_index_find(nodeht, index, (void **) &entry)==SUCCESS) {
+                                               *return_value = **entry;
+                                               zval_copy_ctor(return_value);
+                                               return;
+                                       }
+                               } else {
+                                       nodep = dom_object_get_node(objmap->baseobj);
+                                       if (nodep) {
+                                               if (objmap->nodetype == XML_ATTRIBUTE_NODE || objmap->nodetype == XML_ELEMENT_NODE) {
+                                                       curnode = nodep->children;
+                                                       while (count < index && curnode != NULL) {
+                                                               count++;
+                                                               curnode = curnode->next;
+                                                       }
+                                                       itemnode = curnode;
                                                } else {
-                                                       nodep = nodep->children;
+                                                       if (nodep->type == XML_DOCUMENT_NODE || nodep->type == XML_HTML_DOCUMENT_NODE) {
+                                                               nodep = xmlDocGetRootElement((xmlDoc *) nodep);
+                                                       } else {
+                                                               nodep = nodep->children;
+                                                       }
+                                                       itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
                                                }
-                                               itemnode = dom_get_elements_by_tag_name_ns_raw(nodep, objmap->ns, objmap->local, &count, index);
                                        }
                                }
                        }
                }
-       } else {
-               RETURN_NULL();
        }
 
        if (itemnode) {
index 657999f7961b718e8ed1c23b466dd86bec938037..137dd2c0442dd53a479330ec83a17b0d5d9a6cc9 100644 (file)
@@ -338,6 +338,7 @@ PHP_MINIT_FUNCTION(dom)
        dom_object_handlers.read_property = dom_read_property;
        dom_object_handlers.write_property = dom_write_property;
        dom_object_handlers.get_property_ptr_ptr = NULL;
+       dom_object_handlers.clone_obj = zend_objects_store_clone_obj;
 
        zend_hash_init(&classes, 0, NULL, NULL, 1);
 
@@ -720,13 +721,6 @@ void node_list_unlink(xmlNodePtr node TSRMLS_DC)
 }
 /* }}} end node_list_unlink */
 
-/* {{{ dom_objects_clone */
-void dom_objects_clone(void *object, void **object_clone TSRMLS_DC)
-{
-       /* TODO */
-}
-/* }}} */
-
 #if defined(LIBXML_XPATH_ENABLED)
 /* {{{ dom_xpath_objects_free_storage */
 void dom_xpath_objects_free_storage(void *object TSRMLS_DC)
@@ -821,6 +815,36 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type TSRMLS_DC)
        return intern;
 }
 
+/* {{{ dom_objects_clone */
+void dom_objects_clone(void *object, void **object_clone TSRMLS_DC)
+{
+       dom_object *intern = (dom_object *) object;
+       dom_object *clone;
+       xmlNodePtr node;
+       xmlNodePtr cloned_node;
+
+       clone = dom_objects_set_class(intern->std.ce TSRMLS_CC);
+
+       if (instanceof_function(intern->std.ce, dom_node_class_entry TSRMLS_CC)) {
+               node = (xmlNodePtr)dom_object_get_node((dom_object *) object);
+               if (node != NULL) {
+                       cloned_node = xmlDocCopyNode(node, node->doc, 1);
+                       if (cloned_node != NULL) {
+                               /* If we cloned a document then we must create new doc proxy */
+                               if (cloned_node->doc == node->doc) {
+                                       clone->document = intern->document;
+                               }
+                               php_libxml_increment_doc_ref((php_libxml_node_object *)clone, cloned_node->doc TSRMLS_CC);
+                               php_libxml_increment_node_ptr((php_libxml_node_object *)clone, cloned_node, NULL TSRMLS_CC);
+                       }
+
+               }
+       }
+
+       *object_clone = (void *) clone;
+}
+/* }}} */
+
 /* {{{ dom_objects_new */
 zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
 {
index abaf35b9fabefceb6b515766e64ebfb0460341a3..b467b0365148ad2237cf2d4b8c68668971bd349c 100644 (file)
@@ -85,8 +85,6 @@ int dom_xpath_document_read(dom_object *obj, zval **retval TSRMLS_DC)
 
        if (ctx) {
                docp = (xmlDocPtr) ctx->doc;
-       } else {
-               printf("NONE");
        }
 
        ALLOC_ZVAL(*retval);