diff options
author | Dmitry Stogov <dmitry@php.net> | 2006-06-08 08:56:27 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2006-06-08 08:56:27 +0000 |
commit | 2a7d16f8fd17c85ba72a49b747474ed64363a7e3 (patch) | |
tree | 4a10443dee66599514b9ce182431a27c2e6e791b | |
parent | 6e24feb80d53449c2a6aebcaac99b9a56d41b49d (diff) | |
download | php-git-2a7d16f8fd17c85ba72a49b747474ed64363a7e3.tar.gz |
Proper fix for bug #37707 ("clone $x" must call __clone() enven if result value is not used)
-rwxr-xr-x | Zend/tests/bug37707.phpt | 7 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 5 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 25 |
3 files changed, 30 insertions, 7 deletions
diff --git a/Zend/tests/bug37707.phpt b/Zend/tests/bug37707.phpt index 3657fec989..1964958526 100755 --- a/Zend/tests/bug37707.phpt +++ b/Zend/tests/bug37707.phpt @@ -2,10 +2,15 @@ Bug #37707 (clone without assigning leaks memory) --FILE-- <?php -class testme {} +class testme { + function __clone() { + echo "clonned\n"; + } +} clone new testme(); echo "NO LEAK\n"; ?> --EXPECT-- +clonned NO LEAK diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index f1a7a68f02..9b563ee8e2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2506,12 +2506,15 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } FREE_OP1_IF_VAR(); ZEND_VM_NEXT_OPCODE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index f7ea2a5c90..91ebfe3564 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1831,12 +1831,15 @@ static int ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } ZEND_VM_NEXT_OPCODE(); @@ -4328,12 +4331,15 @@ static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } ZEND_VM_NEXT_OPCODE(); @@ -7407,12 +7413,15 @@ static int ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14295,12 +14304,15 @@ static int ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } ZEND_VM_NEXT_OPCODE(); @@ -19623,12 +19635,15 @@ static int ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr; - if (!EG(exception) && RETURN_VALUE_USED(opline)) { + if (!EG(exception)) { ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr); Z_OBJVAL_P(EX_T(opline->result.u.var).var.ptr) = clone_call(obj TSRMLS_CC); Z_TYPE_P(EX_T(opline->result.u.var).var.ptr) = IS_OBJECT; EX_T(opline->result.u.var).var.ptr->refcount=1; EX_T(opline->result.u.var).var.ptr->is_ref=1; + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr); + } } ZEND_VM_NEXT_OPCODE(); |