implement clone functionality to fix segfault

DomNode->clone() creates new doc proxy if document is cloned
remove printf from xpath
fix remaining invalid object state issues
This commit is contained in:
Rob Richards 2004-02-17 11:13:47 +00:00
parent 0ecd198dc5
commit ec2ea131fb
6 changed files with 170 additions and 129 deletions

View file

@ -268,6 +268,7 @@ 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 != NULL) {
if (objmap->ht == NULL) {
if (objmap->nodetype == DOM_NODESET) {
nodeht = HASH_OF(objmap->baseobjptr);
@ -296,6 +297,7 @@ zend_object_iterator *php_dom_get_iterator(zend_class_entry *ce, zval *object TS
} else {
curnode = php_dom_libxml_hash_iter(objmap->ht, 0);
}
}
if (curnode) {
MAKE_STD_ZVAL(curattr);

View file

@ -61,6 +61,8 @@ int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
int count = 0;
objmap = (dom_nnodemap_object *)obj->ptr;
if (objmap != NULL) {
if (objmap->ht) {
count = xmlHashSize(objmap->ht);
} else {
@ -76,6 +78,7 @@ int dom_namednodemap_length_read(dom_object *obj, zval **retval TSRMLS_DC)
}
}
}
}
MAKE_STD_ZVAL(*retval);
ZVAL_LONG(*retval, count);
@ -110,6 +113,8 @@ 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 != NULL) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
@ -123,6 +128,7 @@ PHP_FUNCTION(dom_namednodemap_get_named_item)
itemnode = (xmlNodePtr)xmlHasProp(nodep, named);
}
}
}
if (itemnode) {
DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);
@ -178,6 +184,8 @@ PHP_FUNCTION(dom_namednodemap_item)
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
objmap = (dom_nnodemap_object *)intern->ptr;
if (objmap != NULL) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
@ -196,8 +204,7 @@ PHP_FUNCTION(dom_namednodemap_item)
itemnode = curnode;
}
}
} else {
RETURN_NULL();
}
}
if (itemnode) {
@ -232,6 +239,8 @@ 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 != NULL) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
itemnode = (xmlNodePtr)xmlHashLookup(objmap->ht, named);
@ -245,6 +254,7 @@ PHP_FUNCTION(dom_namednodemap_get_named_item_ns)
itemnode = (xmlNodePtr)xmlHasNsProp(nodep, named, uri);
}
}
}
if (itemnode) {
DOM_RET_OBJ(rv, itemnode, &ret, objmap->baseobj);

View 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);

View file

@ -55,6 +55,7 @@ int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
HashTable *nodeht;
objmap = (dom_nnodemap_object *)obj->ptr;
if (objmap != NULL) {
if (objmap->ht) {
count = xmlHashSize(objmap->ht);
} else {
@ -84,6 +85,7 @@ int dom_nodelist_length_read(dom_object *obj, zval **retval TSRMLS_DC)
}
}
}
}
MAKE_STD_ZVAL(*retval);
ZVAL_LONG(*retval, count);
@ -118,6 +120,7 @@ PHP_FUNCTION(dom_nodelist_item)
intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
objmap = (dom_nnodemap_object *)intern->ptr;
if (objmap != NULL) {
if (objmap->ht) {
if (objmap->nodetype == XML_ENTITY_NODE) {
itemnode = php_dom_libxml_hash_iter(objmap->ht, index);
@ -153,8 +156,7 @@ PHP_FUNCTION(dom_nodelist_item)
}
}
}
} else {
RETURN_NULL();
}
}
if (itemnode) {

View 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)
{

View 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);