summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2015-11-28 23:38:19 -0800
committerXinchen Hui <laruence@gmail.com>2015-11-28 23:38:19 -0800
commit9397f527248a948e4d3929adb119e7e3519ce5b8 (patch)
tree9629c067cbdc1aade567af639d36a7b22f3e9045
parent5af61aa1cc7bfc6e0087f6176d25fd3a002740b1 (diff)
downloadphp-git-9397f527248a948e4d3929adb119e7e3519ce5b8.tar.gz
Fixed Bug #70967 (Weird error handling for __toString when Error is thrown)
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug26166.phpt4
-rw-r--r--Zend/tests/bug60909_2.phpt2
-rw-r--r--Zend/tests/bug70967.phpt14
-rw-r--r--Zend/zend_object_handlers.c11
-rw-r--r--ext/spl/tests/iterator_036.phpt2
-rw-r--r--tests/classes/tostring_003.phpt2
7 files changed, 31 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 7d7daaea55..5d7a185d33 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP NEWS
?? ??? 2015, PHP 7.0.1
- Core:
+ . Fixed bug #70967 (Weird error handling for __toString when Error is
+ thrown). (Laruence)
. Fixed bug #70970 (Segfault when combining error handler with output
buffering). (Laruence)
. Fixed bug #70958 (Invalid opcode while using ::class as trait method
diff --git a/Zend/tests/bug26166.phpt b/Zend/tests/bug26166.phpt
index 9e31efa442..a77989c7c2 100644
--- a/Zend/tests/bug26166.phpt
+++ b/Zend/tests/bug26166.phpt
@@ -68,7 +68,7 @@ catch (Exception $e) {
--EXPECTF--
Hello World!
===NONE===
-string(56) "Method NoneTest::__toString() must return a string value"
+string(%d) "Method NoneTest::__toString() must return a string value"
===THROW===
-Fatal error: Method ErrorTest::__toString() must not throw an exception in %sbug26166.php on line %d
+Fatal error: Method ErrorTest::__toString() must not throw an exception, caught Exception: This is an error! in %sbug26166.php on line %d
diff --git a/Zend/tests/bug60909_2.phpt b/Zend/tests/bug60909_2.phpt
index d08d9f90fa..1808b1c2fe 100644
--- a/Zend/tests/bug60909_2.phpt
+++ b/Zend/tests/bug60909_2.phpt
@@ -14,7 +14,7 @@ class Bad {
$bad = new Bad();
echo "$bad";
--EXPECTF--
-Fatal error: Method Bad::__toString() must not throw an exception in %sbug60909_2.php on line 0
+Fatal error: Method Bad::__toString() must not throw an exception, caught Exception: Oops, I cannot do this in %sbug60909_2.php on line %d
!!!shutdown!!!
diff --git a/Zend/tests/bug70967.phpt b/Zend/tests/bug70967.phpt
new file mode 100644
index 0000000000..89fc80b3f7
--- /dev/null
+++ b/Zend/tests/bug70967.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #70967 (Weird error handling for __toString when Error is thrown)
+--FILE--
+<?php
+class A {
+ public function __toString() {
+ undefined_function();
+ }
+}
+
+echo (new A);
+?>
+--EXPECTF--
+Fatal error: Method A::__toString() must not throw an exception, caught Error: Call to undefined function undefined_function() in %sbug70967.php on line %d
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 4cd8a4e7c2..0b4f7d24e1 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1526,9 +1526,18 @@ ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int ty
if (ce->__tostring &&
(zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) {
if (UNEXPECTED(EG(exception) != NULL)) {
+ zval *msg, ex, rv;
zval_ptr_dtor(&retval);
+ ZVAL_OBJ(&ex, EG(exception));
EG(exception) = NULL;
- zend_error_noreturn(E_ERROR, "Method %s::__toString() must not throw an exception", ZSTR_VAL(ce->name));
+ msg = zend_read_property(Z_OBJCE(ex), &ex, "message", sizeof("message") - 1, 1, &rv);
+ if (UNEXPECTED(Z_TYPE_P(msg) != IS_STRING)) {
+ ZVAL_EMPTY_STRING(&rv);
+ msg = &rv;
+ }
+ zend_error_noreturn(E_ERROR,
+ "Method %s::__toString() must not throw an exception, caught %s: %s",
+ ZSTR_VAL(ce->name), ZSTR_VAL(Z_OBJCE(ex)->name), Z_STRVAL_P(msg));
return FAILURE;
}
if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
diff --git a/ext/spl/tests/iterator_036.phpt b/ext/spl/tests/iterator_036.phpt
index 9a9e66b3b3..0f668db53f 100644
--- a/ext/spl/tests/iterator_036.phpt
+++ b/ext/spl/tests/iterator_036.phpt
@@ -19,4 +19,4 @@ test(new CachingIterator($ar, 0));
===DONE===
--EXPECTF--
-Fatal error: Method CachingIterator::__toString() must not throw an exception in %siterator_036.php on line %d
+Fatal error: Method CachingIterator::__toString() must not throw an exception, caught BadMethodCallException: CachingIterator does not fetch string value (see CachingIterator::__construct) in %siterator_036.php on line %d
diff --git a/tests/classes/tostring_003.phpt b/tests/classes/tostring_003.phpt
index 8815bd9407..096a7502fe 100644
--- a/tests/classes/tostring_003.phpt
+++ b/tests/classes/tostring_003.phpt
@@ -30,4 +30,4 @@ catch(Exception $e)
?>
====DONE====
--EXPECTF--
-Fatal error: Method Test::__toString() must not throw an exception in %stostring_003.php on line %d
+Fatal error: Method Test::__toString() must not throw an exception, caught Exception: Damn! in %stostring_003.php on line %d