summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/bug52041.phpt50
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h24
3 files changed, 80 insertions, 0 deletions
diff --git a/Zend/tests/bug52041.phpt b/Zend/tests/bug52041.phpt
new file mode 100644
index 0000000000..b481b894da
--- /dev/null
+++ b/Zend/tests/bug52041.phpt
@@ -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
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 6d06374c62..5a0756d753 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2192,6 +2192,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;
retval_ptr->refcount++;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index b001f3c96a..2c4c3c63c6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1809,6 +1809,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;
retval_ptr->refcount++;
@@ -4385,6 +4391,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;
retval_ptr->refcount++;
@@ -7435,6 +7447,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;
retval_ptr->refcount++;
@@ -19865,6 +19883,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;
retval_ptr->refcount++;