summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2010-08-16 09:20:46 +0000
committerDmitry Stogov <dmitry@php.net>2010-08-16 09:20:46 +0000
commitd93cf2a2d0834962f713eceb3304c80d6fb66524 (patch)
tree723f3361b8594633ccb85656bea913ff15533639
parente461c22ea97e1ee7721e45c3627519e939844095 (diff)
downloadphp-git-d93cf2a2d0834962f713eceb3304c80d6fb66524.tar.gz
Bug #52361 (Throwing an exception in a destructor causes invalid catching)
-rw-r--r--Zend/tests/bug52361.phpt35
-rw-r--r--Zend/zend_objects.c6
2 files changed, 37 insertions, 4 deletions
diff --git a/Zend/tests/bug52361.phpt b/Zend/tests/bug52361.phpt
new file mode 100644
index 0000000000..3c2dffa63f
--- /dev/null
+++ b/Zend/tests/bug52361.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #52361 (Throwing an exception in a destructor causes invalid catching)
+--FILE--
+<?php
+class aaa {
+ public function __destruct() {
+ try {
+ throw new Exception(__CLASS__);
+ } catch(Exception $ex) {
+ echo "1. $ex\n";
+ }
+ }
+}
+function bbb() {
+ $a = new aaa();
+ throw new Exception(__FUNCTION__);
+}
+try {
+ bbb();
+ echo "must be skipped !!!";
+} catch(Exception $ex) {
+ echo "2. $ex\n";
+}
+?>
+--EXPECTF--
+1. exception 'Exception' with message 'aaa' in %sbug52361.php:5
+Stack trace:
+#0 %sbug52361.php(16): aaa->__destruct()
+#1 %sbug52361.php(16): bbb()
+#2 {main}
+2. exception 'Exception' with message 'bbb' in %sbug52361.php:13
+Stack trace:
+#0 %sbug52361.php(16): bbb()
+#1 {main}
+
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 6a87284ced..cfd9a4ef82 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -117,15 +117,13 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
zend_error(E_ERROR, "Attempt to destruct pending exception");
} else {
old_exception = EG(exception);
- Z_ADDREF_P(old_exception);
+ EG(exception) = NULL;
}
}
- zend_exception_save(TSRMLS_C);
zend_call_method_with_0_params(&obj, object->ce, &destructor, ZEND_DESTRUCTOR_FUNC_NAME, NULL);
- zend_exception_restore(TSRMLS_C);
if (old_exception) {
if (EG(exception)) {
- zval_ptr_dtor(&old_exception);
+ zend_exception_set_previous(EG(exception), old_exception TSRMLS_CC);
} else {
EG(exception) = old_exception;
}