From d868733cc32f99059f229eedd0cad51471d5500f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Jun 2010 08:22:51 +0000 Subject: [PATCH] Fixed bug #52041 (Memory leak when writing on uninitialized variable returned from function) --- Zend/tests/bug52041.phpt | 75 ++++++++++++++++++++++++++++++++++++++++ Zend/zend_vm_def.h | 6 ++++ Zend/zend_vm_execute.h | 24 +++++++++++++ ext/soap/php_encoding.c | 7 +++- 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/bug52041.phpt 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-- +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); } -- 2.40.0