mirror of
https://github.com/php/php-src.git
synced 2025-01-20 10:43:40 +08:00
Fixed bug #38234 (Exception in __clone makes memory leak)
This commit is contained in:
parent
3f51a6970d
commit
1e71620e8f
18
Zend/tests/bug38234.phpt
Executable file
18
Zend/tests/bug38234.phpt
Executable file
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Bug #38234 (Exception in __clone makes memory leak)
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __clone() {
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
try {
|
||||
$x = new Foo();
|
||||
$y = clone $x;
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
ok
|
@ -2548,7 +2548,11 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -2576,7 +2580,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
|
@ -1759,7 +1759,11 @@ static int ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -1787,7 +1791,7 @@ static int ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
@ -4341,7 +4345,11 @@ static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -4369,7 +4377,7 @@ static int ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
@ -7520,7 +7528,11 @@ static int ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -7548,7 +7560,7 @@ static int ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
@ -14888,7 +14900,11 @@ static int ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -14916,7 +14932,7 @@ static int ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
@ -20531,7 +20547,11 @@ static int ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
clone = ce ? ce->clone : NULL;
|
||||
clone_call = Z_OBJ_HT_P(obj)->clone_obj;
|
||||
if (!clone_call) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
if (ce) {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object of class %v", ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
|
||||
}
|
||||
EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
|
||||
EX_T(opline->result.u.var).var.ptr->refcount++;
|
||||
}
|
||||
@ -20559,7 +20579,7 @@ static int ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
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)) {
|
||||
if (!RETURN_VALUE_USED(opline) || EG(exception)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user