From afd3e39d6697e36d3b92cee5da911e4ea0de3901 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 13 Jul 2016 16:43:47 +0300 Subject: [PATCH] Fixed bug #29368 (The destructor is called when an exception is thrown from the constructor). --- NEWS | 2 ++ UPGRADING | 2 ++ Zend/tests/bug29368_1.phpt | 29 +++++++++++++++++++++++++++++ Zend/zend_vm_def.h | 12 +++--------- Zend/zend_vm_execute.h | 16 ++++------------ 5 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 Zend/tests/bug29368_1.phpt diff --git a/NEWS b/NEWS index 91bba83d05..39261f4d52 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,8 @@ PHP NEWS . Added PHP to SAPI error severity mapping for logs. (Martin Vobruba) . Fixed bug #71911 (Unable to set --enable-debug on building extensions by phpize on Windows). (Yuji Uchiyama) + . Fixed bug #29368 (The destructor is called when an exception is thrown from + the constructor). (Dmitry) - COM: . Fixed bug #72569 (DOTNET/COM array parameters broke in PHP7). (Anatol) diff --git a/UPGRADING b/UPGRADING index 1759590169..adb4741a5b 100644 --- a/UPGRADING +++ b/UPGRADING @@ -47,6 +47,8 @@ PHP 7.1 UPGRADE NOTES syslog error levels. This brings finer differentiation in the error logs in contrary to the previous approach where all the errors are loggged with the notice level only. + . Don't call destructors of incompletely constructed objects, even if they + are kept referenced. See bug #29368 and Zend/tests/bug29368_1.phpt. - JSON: . The serialize_precision is used instead of precision when encoding double diff --git a/Zend/tests/bug29368_1.phpt b/Zend/tests/bug29368_1.phpt new file mode 100644 index 0000000000..09cf334384 --- /dev/null +++ b/Zend/tests/bug29368_1.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #29368.1 (The destructor is called when an exception is thrown from the constructor). +--FILE-- + +--EXPECT-- +Inside constructor +Caught exception! diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d10bd72e9d..f93e89f39f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2500,9 +2500,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { @@ -2537,9 +2535,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY) if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { @@ -3803,9 +3799,7 @@ ZEND_VM_C_LABEL(fcall_end): if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 37d8862d3b..8574b2436c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -492,9 +492,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { @@ -529,9 +527,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ if (UNEXPECTED(EG(exception) != NULL) && (call_info & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { @@ -1017,9 +1013,7 @@ fcall_end: if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } @@ -1146,9 +1140,7 @@ fcall_end: if (UNEXPECTED(EG(exception) != NULL) && (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR)) { #endif GC_REFCOUNT(object)--; - if (GC_REFCOUNT(object) == 1) { - zend_object_store_ctor_failed(object); - } + zend_object_store_ctor_failed(object); } OBJ_RELEASE(object); } -- 2.40.0