summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug30162.phpt52
-rw-r--r--Zend/zend_execute.c6
3 files changed, 58 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 9a89192e86..fd43d14116 100644
--- a/NEWS
+++ b/NEWS
@@ -76,6 +76,8 @@ PHP NEWS
(Dmitry)
- Fixed bug #30332 (zend.ze1_compatibility_mode isnt fully compatable with
array_push()). (Dmitry)
+- Fixed bug #30162 (Catching exception in constructor couses lose of $this).
+ (Dmitry)
- Fixed bug #30126 (Enhancement for error message for abstract classes).
(Marcus)
- Fixed bug #29944 (Function defined in switch, crashes). (Dmitry)
diff --git a/Zend/tests/bug30162.phpt b/Zend/tests/bug30162.phpt
new file mode 100755
index 0000000000..ae11f8ff8b
--- /dev/null
+++ b/Zend/tests/bug30162.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Bug #30162 (Catching exception in constructor couses lose of $this)
+--FILE--
+<?php
+class FIIFO {
+
+ public function __construct() {
+ $this->x = "x";
+ throw new Exception;
+ }
+
+}
+
+class hariCow extends FIIFO {
+
+ public function __construct() {
+ try {
+ parent::__construct();
+ } catch(Exception $e) {
+ }
+ $this->y = "y";
+ try {
+ $this->z = new FIIFO;
+ } catch(Exception $e) {
+ }
+ }
+
+ public function __toString() {
+ return "Rusticus in asino sedet.";
+ }
+
+}
+
+try {
+ $db = new FIIFO();
+} catch(Exception $e) {
+}
+var_dump($db);
+
+$db = new hariCow;
+
+var_dump($db);
+?>
+--EXPECTF--
+Notice: Undefined variable: db in %sbug30162.php on line 35
+NULL
+object(hariCow)#1 (2) {
+ ["x"]=>
+ string(1) "x"
+ ["y"]=>
+ string(1) "y"
+}
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index e282f9056f..9bac1bd941 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -2815,9 +2815,11 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
if (EG(exception) && EX(fbc) && EX(fbc)->common.fn_flags&ZEND_ACC_CTOR) {
EG(This)->refcount--;
if (EG(This)->refcount == 1) {
- zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+ zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+ }
+ if (should_change_scope && EG(This) != current_this) {
+ zval_ptr_dtor(&EG(This));
}
- zval_ptr_dtor(&EG(This));
} else if (should_change_scope) {
zval_ptr_dtor(&EG(This));
}