diff options
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/exception_delayed_message.phpt | 41 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 3 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 2 |
3 files changed, 44 insertions, 2 deletions
diff --git a/Zend/tests/exception_delayed_message.phpt b/Zend/tests/exception_delayed_message.phpt new file mode 100644 index 0000000000..e9f7a1fa21 --- /dev/null +++ b/Zend/tests/exception_delayed_message.phpt @@ -0,0 +1,41 @@ +--TEST-- +Exception with delayed message computation +--FILE-- +<?php + +class MyException extends Exception { + public $message; + public $messageCallback; + + public function __construct() { + $this->messageCallback = static function() { + return "Foobar"; + }; + $this->message = new class($this->message, $this->messageCallback) { + private $message; + private $messageCallback; + + public function __construct(&$message, &$messageCallback) + { + $this->message = &$message; + $this->messageCallback = &$messageCallback; + } + + public function __toString(): string + { + $messageCallback = $this->messageCallback; + $this->messageCallback = null; + return $this->message = $messageCallback(); + } + }; + } +} + +throw new MyException; + +?> +--EXPECTF-- +Fatal error: Uncaught MyException: Foobar in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index a039d18668..31738b6a86 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -414,8 +414,7 @@ ZEND_METHOD(Exception, getMessage) ZEND_PARSE_PARAMETERS_NONE(); prop = GET_PROPERTY(ZEND_THIS, ZEND_STR_MESSAGE); - ZVAL_DEREF(prop); - ZVAL_COPY(return_value, prop); + RETURN_STR(zval_get_string(prop)); } /* }}} */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 7abc87d75e..ce5411b040 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1800,7 +1800,9 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj, zend_class_entry *ce = readobj->ce; if (ce->__tostring) { zval retval; + GC_ADDREF(readobj); zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval); + zend_object_release(readobj); if (EXPECTED(Z_TYPE(retval) == IS_STRING)) { ZVAL_COPY_VALUE(writeobj, &retval); return SUCCESS; |