]> granicus.if.org Git - php/commitdiff
MFH: fix leak appearing when appending data to unnamed attribute
authorAntony Dovgal <tony2001@php.net>
Wed, 23 Jan 2008 09:59:42 +0000 (09:59 +0000)
committerAntony Dovgal <tony2001@php.net>
Wed, 23 Jan 2008 09:59:42 +0000 (09:59 +0000)
ext/simplexml/simplexml.c
ext/simplexml/tests/bug37076_1.phpt [new file with mode: 0644]

index 1c65a72fe6b9273a7336c07d5de8cc8d141b2a26..19ab0ea5e52b89b10bfd56f8171ef0fc110cabb0 100644 (file)
@@ -461,7 +461,7 @@ static void change_node_zval(xmlNodePtr node, zval *value TSRMLS_DC)
 
 /* {{{ sxe_property_write()
  */
-static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool elements, zend_bool attribs, xmlNodePtr *pnewnode TSRMLS_DC)
+static int sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_bool elements, zend_bool attribs, xmlNodePtr *pnewnode TSRMLS_DC)
 {
        php_sxe_object *sxe;
        xmlNodePtr      node;
@@ -475,6 +475,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
        int             test = 0;
        int                             new_value = 0;
        long            cnt = 0;
+       int                             retval = SUCCESS;
        zval            tmp_zv, trim_zv, value_copy;
 
        sxe = php_sxe_fetch_object(object TSRMLS_CC);
@@ -489,7 +490,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                         * and this is during runtime.
                         */
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
-                       return;
+                       return FAILURE;
                }
        } else {
                if (Z_TYPE_P(member) != IS_STRING) {
@@ -506,7 +507,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                        if (member == &tmp_zv) {
                                zval_dtor(&tmp_zv);
                        }
-                       return;
+                       return FAILURE;
                }
        }
 
@@ -530,7 +531,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                         * and this is during runtime.
                         */
                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create unnamed attribute");
-                       return;
+                       return FAILURE;
                }
                if (attribs && !node && sxe->iter.type == SXE_ITER_ELEMENT) {
                        node = xmlNewChild(mynode, mynode->ns, sxe->iter.name, NULL);
@@ -572,7 +573,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                                        zval_dtor(&tmp_zv);
                                }
                                zend_error(E_WARNING, "It is not yet possible to assign complex types to %s", attribs ? "attributes" : "properties");
-                               return;
+                               return FAILURE;
                }
        }
 
@@ -607,7 +608,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                        if (!member || Z_TYPE_P(member) == IS_LONG) {
                                if (node->type == XML_ATTRIBUTE_NODE) {
                                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot create duplicate attribute");
-                                       return;
+                                       return FAILURE;
                                }
 
                                if (sxe->iter.type == SXE_ITER_NONE) {
@@ -615,6 +616,7 @@ static void sxe_prop_dim_write(zval *object, zval *member, zval *value, zend_boo
                                        ++counter;
                                        if (member && Z_LVAL_P(member) > 0) {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only 0 such elements exist", mynode->name, Z_LVAL_P(member));
+                                               retval = FAILURE;
                                        }
                                } else if (member) {
                                        newnode = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
@@ -651,6 +653,7 @@ next_iter:
                        }
                } else if (counter > 1) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot assign to an array of nodes (duplicate subnodes or attr detected)");
+                       retval = FAILURE;
                } else if (elements) {
                        if (!node) {
                                if (!member || Z_TYPE_P(member) == IS_LONG) {
@@ -661,12 +664,14 @@ next_iter:
                        } else if (!member || Z_TYPE_P(member) == IS_LONG) {
                                if (member && cnt < Z_LVAL_P(member)) {
                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element %s number %ld when only %ld such elements exist", mynode->name, Z_LVAL_P(member), cnt);
+                                       retval = FAILURE;
                                }
                                newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
                        }
                } else if (attribs) {
                        if (Z_TYPE_P(member) == IS_LONG) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot change attribute number %ld when only %d attributes exist", Z_LVAL_P(member), nodendx);
+                               retval = FAILURE;
                        } else {
                                newnode = (xmlNodePtr)xmlNewProp(node, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
                        }
@@ -685,6 +690,7 @@ next_iter:
        if (new_value) {
                zval_ptr_dtor(&value);
        }
+       return retval;
 }
 /* }}} */
 
@@ -722,7 +728,9 @@ static zval** sxe_property_get_adr(zval *object, zval *member TSRMLS_DC) /* {{{
        if (node) {
                return NULL;
        }
-       sxe_prop_dim_write(object, member, NULL, 1, 0, &node TSRMLS_CC);
+       if (sxe_prop_dim_write(object, member, NULL, 1, 0, &node TSRMLS_CC) != SUCCESS) {
+               return NULL;
+       }
        type = SXE_ITER_NONE;
        name = NULL;
 
diff --git a/ext/simplexml/tests/bug37076_1.phpt b/ext/simplexml/tests/bug37076_1.phpt
new file mode 100644 (file)
index 0000000..d226004
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #37076 (SimpleXML ignores .=) (appending to unnamed attribute)
+--FILE--
+<?php
+$xml = simplexml_load_string("<root><foo /></root>");
+$xml->{""} .= "bar";
+print $xml->asXML();
+?>
+===DONE===
+--EXPECTF--
+Warning: main(): Cannot write or create unnamed element in %s on line %d
+
+Warning: main(): Cannot write or create unnamed element in %s on line %d
+<?xml version="1.0"?>
+<root><foo/></root>
+===DONE===