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