diff options
author | Dmitry Stogov <dmitry@php.net> | 2010-06-15 08:22:51 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2010-06-15 08:22:51 +0000 |
commit | 113d07c98103d164c87a42bfae544a764876f88f (patch) | |
tree | 9d42e63c1e354e8732f3fdbb482713c579ac1cef | |
parent | 6b74d61957658b2ba4d085d7c87f257d28a26388 (diff) | |
download | php-git-113d07c98103d164c87a42bfae544a764876f88f.tar.gz |
Fixed bug #52041 (Memory leak when writing on uninitialized variable returned from function)
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug52041.phpt | 50 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 6 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 24 | ||||
-rw-r--r-- | ext/soap/php_encoding.c | 7 |
5 files changed, 88 insertions, 1 deletions
@@ -18,6 +18,8 @@ PHP NEWS - Fixed a possible arbitrary memory access inside sqlite extension. Reported by Mateusz Kocielski. (Ilia) +- Fixed bug #52041 (Memory leak when writing on uninitialized variable returned + from function). (Dmitry) - Fixed bug #52019 (make lcov doesn't support TESTS variable anymore). (Patrick) - Fixed bug #51911 (ReflectionParameter::getDefaultValue() memory leaks with constant array). (Felipe) 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++; diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 3bd6901adc..8a5e6e75ab 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1523,8 +1523,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 (tmp->refcount == 0) { + zval_dtor(tmp); + efree(tmp); } zval_ptr_dtor(&redo_any); } |