summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2010-06-15 08:22:51 +0000
committerDmitry Stogov <dmitry@php.net>2010-06-15 08:22:51 +0000
commitd868733cc32f99059f229eedd0cad51471d5500f (patch)
treeffaab92bae0dc3b2a423cb6b8a948c8a78a095f6
parent2f838ef5471a61e5e62077c8cbc6735ba3be9be1 (diff)
downloadphp-git-d868733cc32f99059f229eedd0cad51471d5500f.tar.gz
Fixed bug #52041 (Memory leak when writing on uninitialized variable returned from function)
-rw-r--r--Zend/tests/bug52041.phpt75
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h24
-rw-r--r--ext/soap/php_encoding.c7
4 files changed, 111 insertions, 1 deletions
diff --git a/Zend/tests/bug52041.phpt b/Zend/tests/bug52041.phpt
new file mode 100644
index 0000000000..f2eb8d3ed8
--- /dev/null
+++ b/Zend/tests/bug52041.phpt
@@ -0,0 +1,75 @@
+--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
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined variable: x in %stests/bug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 15
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 16
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 16
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 17
+
+Notice: Undefined variable: x in %sbug52041.php on line 3
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 18
+
+Notice: Undefined offset: 0 in %sbug52041.php on line 18
+
+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 5804dd3e2a..a5c2fa3ac9 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2781,6 +2781,12 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
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);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c456c7e8a4..d06091bc54 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1742,6 +1742,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
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);
@@ -6064,6 +6070,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
@@ -10288,6 +10300,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
@@ -26267,6 +26285,12 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
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);
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index 4295ffbd76..047734c2a5 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -1548,8 +1548,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);
}