]> granicus.if.org Git - php/commitdiff
Fixed bug #52041 (Memory leak when writing on uninitialized variable returned from...
authorDmitry Stogov <dmitry@php.net>
Tue, 15 Jun 2010 08:22:51 +0000 (08:22 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 15 Jun 2010 08:22:51 +0000 (08:22 +0000)
Zend/tests/bug52041.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/soap/php_encoding.c

diff --git a/Zend/tests/bug52041.phpt b/Zend/tests/bug52041.phpt
new file mode 100644 (file)
index 0000000..b481b89
--- /dev/null
@@ -0,0 +1,50 @@
+--TEST--
+Bug #52041 (Memory leak when writing on uninitialized variable returned from function)
+--FILE--
+<?php
+function foo() {
+       return $x;
+}
+
+foo()->a = 1;
+foo()->a->b = 2;
+foo()->a++;
+foo()->a->b++;
+foo()->a += 2;
+foo()->a->b += 2;
+
+//foo()[0] = 1;
+//foo()[0][0] = 2;
+//foo()[0]++;
+//foo()[0][0]++;
+//foo()[0] += 2;
+//foo()[0][0] += 2;
+var_dump(foo());
+?>
+--EXPECTF--
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 6
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 7
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 8
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 9
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 10
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Strict Standards: Creating default object from empty value in %sbug52041.php on line 11
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+NULL
index e953d405f0530f83475d5c1f06c74e31ba8bc81b..cd26f5e8e65a3fa0e81b87217f3acddce09ee20e 100644 (file)
@@ -2493,6 +2493,12 @@ ZEND_VM_C_LABEL(return_by_value):
                                INIT_PZVAL_COPY(ret, retval_ptr);
                                zval_copy_ctor(ret);
                                *EG(return_value_ptr_ptr) = ret;
+                       } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
+                                  retval_ptr == &EG(uninitialized_zval)) {
+                               zval *ret;
+
+                               ALLOC_INIT_ZVAL(ret);
+                               *EG(return_value_ptr_ptr) = ret;
                        } else {
                                *EG(return_value_ptr_ptr) = retval_ptr;
                                Z_ADDREF_P(retval_ptr);
index e1e1b976b16f56a0ed73f9e857964a1f10dadbfa..45f5c62c2add30fe9be0b1ebe7eac4db6a03c9fd 100644 (file)
@@ -1664,6 +1664,12 @@ return_by_value:
                                INIT_PZVAL_COPY(ret, retval_ptr);
                                zval_copy_ctor(ret);
                                *EG(return_value_ptr_ptr) = ret;
+                       } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
+                                  retval_ptr == &EG(uninitialized_zval)) {
+                               zval *ret;
+
+                               ALLOC_INIT_ZVAL(ret);
+                               *EG(return_value_ptr_ptr) = ret;
                        } else {
                                *EG(return_value_ptr_ptr) = retval_ptr;
                                Z_ADDREF_P(retval_ptr);
@@ -4931,6 +4937,12 @@ return_by_value:
                                INIT_PZVAL_COPY(ret, retval_ptr);
                                zval_copy_ctor(ret);
                                *EG(return_value_ptr_ptr) = ret;
+                       } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
+                                  retval_ptr == &EG(uninitialized_zval)) {
+                               zval *ret;
+
+                               ALLOC_INIT_ZVAL(ret);
+                               *EG(return_value_ptr_ptr) = ret;
                        } else {
                                *EG(return_value_ptr_ptr) = retval_ptr;
                                Z_ADDREF_P(retval_ptr);
@@ -8167,6 +8179,12 @@ return_by_value:
                                INIT_PZVAL_COPY(ret, retval_ptr);
                                zval_copy_ctor(ret);
                                *EG(return_value_ptr_ptr) = ret;
+                       } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
+                                  retval_ptr == &EG(uninitialized_zval)) {
+                               zval *ret;
+
+                               ALLOC_INIT_ZVAL(ret);
+                               *EG(return_value_ptr_ptr) = ret;
                        } else {
                                *EG(return_value_ptr_ptr) = retval_ptr;
                                Z_ADDREF_P(retval_ptr);
@@ -22027,6 +22045,12 @@ return_by_value:
                                INIT_PZVAL_COPY(ret, retval_ptr);
                                zval_copy_ctor(ret);
                                *EG(return_value_ptr_ptr) = ret;
+                       } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
+                                  retval_ptr == &EG(uninitialized_zval)) {
+                               zval *ret;
+
+                               ALLOC_INIT_ZVAL(ret);
+                               *EG(return_value_ptr_ptr) = ret;
                        } else {
                                *EG(return_value_ptr_ptr) = retval_ptr;
                                Z_ADDREF_P(retval_ptr);
index 3e63dbe02aa0dc6761f86ca84f4b2f89f7efebdf..bc2df3cd0c73460b17f06d46467a42fe22337f9a 100644 (file)
@@ -1562,8 +1562,13 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
                        }
                        model_to_zval_object(ret, sdlType->model, data, sdl TSRMLS_CC);
                        if (redo_any) {
-                               if (get_zval_property(ret, "any" TSRMLS_CC) == NULL) {
+                               zval *tmp = get_zval_property(ret, "any" TSRMLS_CC);
+
+                               if (tmp == NULL) {
                                        model_to_zval_any(ret, data->children TSRMLS_CC);
+                               } else if (Z_REFCOUNT_P(tmp) == 0) {
+                                       zval_dtor(tmp);
+                                       efree(tmp);
                                }
                                zval_ptr_dtor(&redo_any);
                        }