]> granicus.if.org Git - php/commitdiff
Proper fix for bug #37707 ("clone $x" must call __clone() enven if result value is...
authorDmitry Stogov <dmitry@php.net>
Thu, 8 Jun 2006 08:56:27 +0000 (08:56 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 8 Jun 2006 08:56:27 +0000 (08:56 +0000)
Zend/tests/bug37707.phpt
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 3657fec989db86f4593e531095f35ec45d522729..1964958526b76abde03a7fce0093f67dbb720c68 100755 (executable)
@@ -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
 
index f1a7a68f02fc9d6e558a5991986c37dbc232eb3e..9b563ee8e294510d56d994ca98ddfe000d63f7f0 100644 (file)
@@ -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();
index f7ea2a5c90efabdf1ddc5ce35469702d0ab2da88..91ebfe35646182b4fa0fe565d2185ca9d5a40a76 100644 (file)
@@ -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();