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

index 336707c8fffe6abdbd6561da33ffd0a0685c6f43..879199ed6dddec2a616c1173241ce87e0370a611 100644 (file)
@@ -458,7 +458,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;
@@ -472,6 +472,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);
@@ -486,7 +487,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) {
@@ -503,7 +504,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;
                }
        }
 
@@ -527,7 +528,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);
@@ -565,7 +566,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;
                }
        }
 
@@ -600,7 +601,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) {
@@ -608,6 +609,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);
@@ -644,6 +646,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) {
@@ -654,12 +657,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);
                        }
@@ -678,6 +683,7 @@ next_iter:
        if (new_value) {
                zval_ptr_dtor(&value);
        }
+       return retval;
 }
 /* }}} */
 
@@ -714,7 +720,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..3d288a1
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #37076 (SimpleXML ignores .=) (appending to unnamed attribute)
+--FILE--
+<?php
+$xml = simplexml_load_string("<root><foo /></root>");
+$xml->{""} .= "bar";
+print $xml->asXML();
+?>
+===DONE===
+--EXPECT--
+<?xml version="1.0"?>
+<root><foo/></root>
+===DONE===