rrichards Thu Jan 22 16:30:16 2004 EDT Modified files: /php-src/ext/simplexml php_simplexml.h simplexml.c Log: Fix bug #27010: segfault after returning nodes with children() Fix segfault in match_ns when matching prefix and node without ns some general cleanup and code consilidation better write handling - engine support dependent better isset handling - engine support dependent namespace fixes for reading/writing
http://cvs.php.net/diff.php/php-src/ext/simplexml/php_simplexml.h?r1=1.16&r2=1.17&ty=u Index: php-src/ext/simplexml/php_simplexml.h diff -u php-src/ext/simplexml/php_simplexml.h:1.16 php-src/ext/simplexml/php_simplexml.h:1.17 --- php-src/ext/simplexml/php_simplexml.h:1.16 Sun Jan 18 10:15:55 2004 +++ php-src/ext/simplexml/php_simplexml.h Thu Jan 22 16:30:14 2004 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_simplexml.h,v 1.16 2004/01/18 15:15:55 helly Exp $ */ +/* $Id: php_simplexml.h,v 1.17 2004/01/22 21:30:14 rrichards Exp $ */ #ifndef PHP_SIMPLEXML_H #define PHP_SIMPLEXML_H @@ -59,7 +59,6 @@ HashTable *properties; xmlXPathContextPtr xpath; struct { - php_libxml_node_ptr *node; int itertype; char *name; char *nsprefix; @@ -70,9 +69,8 @@ #define SXE_ITER_NONE 0 #define SXE_ITER_ELEMENT 1 -#define SXE_ITER_ATTR 2 -#define SXE_ITER_CHILD 3 -#define SXE_ITER_ATTRLIST 4 +#define SXE_ITER_CHILD 2 +#define SXE_ITER_ATTRLIST 3 #ifdef ZTS #define SIMPLEXML_G(v) TSRMG(simplexml_globals_id, zend_simplexml_globals *, v) http://cvs.php.net/diff.php/php-src/ext/simplexml/simplexml.c?r1=1.121&r2=1.122&ty=u Index: php-src/ext/simplexml/simplexml.c diff -u php-src/ext/simplexml/simplexml.c:1.121 php-src/ext/simplexml/simplexml.c:1.122 --- php-src/ext/simplexml/simplexml.c:1.121 Wed Jan 21 09:04:46 2004 +++ php-src/ext/simplexml/simplexml.c Thu Jan 22 16:30:14 2004 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: simplexml.c,v 1.121 2004/01/21 14:04:46 rrichards Exp $ */ +/* $Id: simplexml.c,v 1.122 2004/01/22 21:30:14 rrichards Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -121,14 +121,41 @@ return 1; } - if (!xmlStrcmp(node->ns->href, name)) { + if (node->ns && !xmlStrcmp(node->ns->href, name)) { return 1; } return 0; } /* }}} */ - + +/* {{{ sxe_get_element_node() + */ +static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node) { + long nodendx = 0; + + if (sxe->iter.type == SXE_ITER_NONE) { + return NULL; + } + while (node && nodendx <= offset) { + SKIP_TEXT(node) + if (node->type == XML_ELEMENT_NODE && match_ns(sxe, node, sxe->iter.nsprefix)) { + if (sxe->iter.type == SXE_ITER_CHILD || ( + sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name))) { + if (nodendx == offset) { + break; + } + nodendx++; + } + } +next_iter: + node = node->next; + } + + return node; +} +/* }}} */ + /* {{{ sxe_prop_dim_read() */ static zval * sxe_prop_dim_read(zval *object, zval *member, zend_bool elements, zend_bool attribs, zend_bool silent TSRMLS_DC) @@ -140,7 +167,6 @@ xmlAttrPtr attr; zval tmp_zv; int nodendx = 0; - char *prefix; sxe = php_sxe_fetch_object(object TSRMLS_CC); @@ -179,7 +205,7 @@ while (attr && nodendx <= Z_LVAL_P(member)) { if (match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { if (nodendx == Z_LVAL_P(member)) { - _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC); + _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC); break; } nodendx++; @@ -189,7 +215,7 @@ } else { while (attr) { if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { - _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC); + _node_as_zval(sxe, (xmlNodePtr) attr, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC); break; } attr = attr->next; @@ -203,31 +229,12 @@ php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, node, NULL TSRMLS_CC); } if (Z_TYPE_P(member) == IS_LONG) { - if (sxe->iter.type == SXE_ITER_NONE || sxe->iter.type == SXE_ITER_ATTR) { - node = NULL; - } - - prefix = sxe->iter.nsprefix; - - while (node && nodendx <= Z_LVAL_P(member)) { - SKIP_TEXT(node) - if (node->type == XML_ELEMENT_NODE) { - if (match_ns(sxe, node, prefix)) { - if (sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name)) { - if (nodendx == Z_LVAL_P(member)) { - break; - } - nodendx++; - } - } else { - break; - } - } -next_iter: - node = node->next; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); } + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node); if (node) { - _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, NULL TSRMLS_CC); + _node_as_zval(sxe, node, return_value, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC); } } else { _node_as_zval(sxe, node, return_value, SXE_ITER_ELEMENT, name, sxe->iter.nsprefix TSRMLS_CC); @@ -295,7 +302,7 @@ xmlAttrPtr attr = NULL; int counter = 0; int is_attr = 0; - int itercount = 0; + int nodendx = 0; zval tmp_zv, trim_zv; if (!member) { @@ -307,13 +314,15 @@ return; } + + sxe = php_sxe_fetch_object(object TSRMLS_CC); + if (Z_TYPE_P(member) == IS_LONG) { - if (Z_LVAL_P(member) == 0) { - elements = 1; + if (sxe->iter.type != SXE_ITER_ATTRLIST) { attribs = 0; - } else - return; - } else + elements = 1; + } + } else { if (Z_TYPE_P(member) != IS_STRING) { trim_zv = *member; zval_copy_ctor(&trim_zv); @@ -323,38 +332,57 @@ member = &tmp_zv; } - if (!Z_STRLEN_P(member)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write or create unnamed %s", attribs ? "attribute" : "element"); - if (member == &tmp_zv) { - zval_dtor(&tmp_zv); + if (!Z_STRLEN_P(member)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot write or create unnamed %s", attribs ? "attribute" : "element"); + if (member == &tmp_zv) { + zval_dtor(&tmp_zv); + } + return; } - return; } name = Z_STRVAL_P(member); - sxe = php_sxe_fetch_object(object TSRMLS_CC); GET_NODE(sxe, node); - node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } if (node) { if (attribs) { attr = node->properties; - while (attr) { - if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { - is_attr = 1; - ++counter; - break; + if (Z_TYPE_P(member) == IS_LONG) { + while (attr && nodendx <= Z_LVAL_P(member)) { + if (match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + if (nodendx == Z_LVAL_P(member)) { + is_attr = 1; + ++counter; + break; + } + nodendx++; + } + attr = attr->next; + } + } else { + while (attr) { + if (!xmlStrcmp(attr->name, name) && match_ns(sxe, (xmlNodePtr) attr, sxe->iter.nsprefix)) { + is_attr = 1; + ++counter; + break; + } + attr = attr->next; } - attr = attr->next; } } if (elements) { if (Z_TYPE_P(member) == IS_LONG) { - newnode = node; - ++counter; + newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node); + if (newnode) { + ++counter; + } } else { node = node->children; while (node) { @@ -366,7 +394,6 @@ } next_iter: - itercount++; node = node->next; } } @@ -384,17 +411,19 @@ } else if (counter > 1) { php_error(E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)\n"); } else { - switch (Z_TYPE_P(value)) { - case IS_LONG: - case IS_BOOL: - case IS_DOUBLE: - case IS_NULL: - convert_to_string(value); - case IS_STRING: - newnode = (xmlNodePtr)xmlNewProp(node, name, Z_STRVAL_P(value)); - break; - default: - php_error(E_WARNING, "It is not yet possible to assign complex types to attributes"); + if (attribs) { + switch (Z_TYPE_P(value)) { + case IS_LONG: + case IS_BOOL: + case IS_DOUBLE: + case IS_NULL: + convert_to_string(value); + case IS_STRING: + newnode = (xmlNodePtr)xmlNewProp(node, name, Z_STRVAL_P(value)); + break; + default: + php_error(E_WARNING, "It is not yet possible to assign complex types to attributes"); + } } } } @@ -430,13 +459,23 @@ xmlNodePtr node; xmlAttrPtr attr = NULL; int exists = 0; - int nodendx = 0; sxe = php_sxe_fetch_object(object TSRMLS_CC); + name = Z_STRVAL_P(member); GET_NODE(sxe, node); + if (Z_TYPE_P(member) == IS_LONG) { + if (sxe->iter.type != SXE_ITER_ATTRLIST) { + attribs = 0; + elements = 1; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); + } + } + } + if (sxe->iter.type != SXE_ITER_CHILD && sxe->iter.type != SXE_ITER_ATTRLIST) { node = php_sxe_get_first_node(sxe, node TSRMLS_CC); } @@ -456,31 +495,14 @@ if (elements) { if (Z_TYPE_P(member) == IS_LONG) { - if (sxe->iter.type == SXE_ITER_NONE || sxe->iter.type == SXE_ITER_ATTR) { - node = NULL; - } - - while (node && nodendx <= Z_LVAL_P(member)) { - SKIP_TEXT(node) - if (node->type == XML_ELEMENT_NODE) { - if (match_ns(sxe, node, sxe->iter.nsprefix)) { - if (sxe->iter.type == SXE_ITER_ELEMENT && !xmlStrcmp(node->name, sxe->iter.name)) { - if (nodendx == Z_LVAL_P(member)) { - break; - } - nodendx++; - } - } else { - break; - } - } -next_iter: - node = node->next; + if (sxe->iter.type == SXE_ITER_CHILD) { + node = php_sxe_get_first_node(sxe, node TSRMLS_CC); } + node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node); } if (node) { - return 1; + exists = 1; } } } @@ -1086,6 +1108,10 @@ intern = ecalloc(1, sizeof(php_sxe_object)); intern->zo.ce = ce; + intern->iter.type = SXE_ITER_NONE; + intern->iter.nsprefix = NULL; + intern->iter.name = NULL; + ALLOC_HASHTABLE(intern->zo.properties); zend_hash_init(intern->zo.properties, 0, NULL, ZVAL_PTR_DTOR, 0); @@ -1188,7 +1214,6 @@ sxe = php_sxe_object_new(ce TSRMLS_CC); php_libxml_increment_doc_ref((php_libxml_node_object *)sxe, docp TSRMLS_CC); - sxe->iter.type = SXE_ITER_NONE; php_libxml_increment_node_ptr((php_libxml_node_object *)sxe, xmlDocGetRootElement(docp), NULL TSRMLS_CC); return_value->type = IS_OBJECT; @@ -1261,7 +1286,6 @@ case SXE_ITER_NONE: node = node->children; break; - case SXE_ITER_ATTR: case SXE_ITER_ATTRLIST: node = (xmlNodePtr) node->properties; } @@ -1271,7 +1295,7 @@ while (node) { SKIP_TEXT(node); - if (sxe->iter.type != SXE_ITER_ATTR && sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) { + if (sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) { if (sxe->iter.type == SXE_ITER_ELEMENT) { if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix)) { break; @@ -1283,14 +1307,8 @@ } } else { if (node->type == XML_ATTRIBUTE_NODE) { - if (sxe->iter.type == SXE_ITER_ATTR) { - if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, sxe->iter.nsprefix)) { - break; - } - } else { - if (match_ns(sxe, node, sxe->iter.nsprefix)) { - break; - } + if (match_ns(sxe, node, sxe->iter.nsprefix)) { + break; } } } @@ -1300,7 +1318,7 @@ if (node) { ALLOC_INIT_ZVAL(sxe->iter.data); - _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, NULL TSRMLS_CC); + _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC); } } @@ -1363,7 +1381,7 @@ ZEND_API void php_sxe_move_forward_iterator(php_sxe_object *sxe TSRMLS_DC) { - xmlNodePtr node; + xmlNodePtr node = NULL; php_sxe_object *intern; char *prefix; @@ -1372,8 +1390,6 @@ GET_NODE(intern, node) zval_ptr_dtor(&sxe->iter.data); sxe->iter.data = NULL; - } else { - node = sxe->iter.node->node; } if (node) { @@ -1385,7 +1401,7 @@ while (node) { SKIP_TEXT(node); - if (sxe->iter.type != SXE_ITER_ATTR && sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) { + if (sxe->iter.type != SXE_ITER_ATTRLIST && node->type == XML_ELEMENT_NODE) { if (sxe->iter.type == SXE_ITER_ELEMENT) { if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, prefix)) { break; @@ -1397,14 +1413,8 @@ } } else { if (node->type == XML_ATTRIBUTE_NODE) { - if (sxe->iter.type == SXE_ITER_ATTR) { - if (!xmlStrcmp(node->name, sxe->iter.name) && match_ns(sxe, node, sxe->iter.nsprefix)) { - break; - } - } else { - if (match_ns(sxe, node, sxe->iter.nsprefix)) { - break; - } + if (match_ns(sxe, node, sxe->iter.nsprefix)) { + break; } } } @@ -1414,7 +1424,7 @@ if (node) { ALLOC_INIT_ZVAL(sxe->iter.data); - _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, NULL TSRMLS_CC); + _node_as_zval(sxe, node, sxe->iter.data, SXE_ITER_NONE, NULL, sxe->iter.nsprefix TSRMLS_CC); } } @@ -1559,7 +1569,7 @@ { php_info_print_table_start(); php_info_print_table_header(2, "Simplexml support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.121 $"); + php_info_print_table_row(2, "Revision", "$Revision: 1.122 $"); php_info_print_table_row(2, "Schema support", #ifdef LIBXML_SCHEMAS_ENABLED "enabled");
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php