Commit 08b616e2f53 for php.net
commit 08b616e2f5384d03f06feaceb0ea60a773c39949
Author: Máté Kocsis <kocsismate@woohoolabs.com>
Date: Sat May 31 22:31:48 2025 +0200
Backport relevant changes of https://github.com/php/php-src/pull/18719
These property writes may now throw exceptions because of property hooks, and this was not handled previously.
diff --git a/Zend/tests/exception_027.phpt b/Zend/tests/exception_027.phpt
new file mode 100644
index 00000000000..805127420b3
--- /dev/null
+++ b/Zend/tests/exception_027.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Exception properties are overridden by property hooks
+--FILE--
+<?php
+class MyException extends Exception
+{
+ private bool $modified = false;
+
+ protected $code {
+ set($value) {
+ if ($this->modified) {
+ throw new Exception();
+ } else {
+ $this->modified = true;
+
+ $this->code = $value;
+ }
+ }
+ }
+}
+
+$e = new MyException("foo", 1, new Exception());
+
+try {
+ $e->__construct("bar", 2, null);
+} catch (Exception) {
+}
+
+var_dump($e->getMessage());
+var_dump($e->getCode());
+var_dump($e->getPrevious()::class);
+
+?>
+--EXPECTF--
+string(3) "bar"
+int(1)
+string(9) "Exception"
\ No newline at end of file
diff --git a/Zend/tests/exception_028.phpt b/Zend/tests/exception_028.phpt
new file mode 100644
index 00000000000..233b545fb36
--- /dev/null
+++ b/Zend/tests/exception_028.phpt
@@ -0,0 +1,43 @@
+--TEST--
+ErrorException properties are overridden by property hooks
+--FILE--
+<?php
+class MyException extends ErrorException
+{
+ private bool $modified = false;
+
+ protected $code {
+ set($value) {
+ if ($this->modified) {
+ throw new Exception();
+ } else {
+ $this->modified = true;
+
+ $this->code = $value;
+ }
+ }
+ }
+}
+
+$e = new MyException("foo", 1, E_NOTICE, "file1", 1, new Exception());
+
+try {
+ $e->__construct("bar", 2, E_WARNING, "file2", 2, null);
+} catch (Exception) {
+}
+
+var_dump($e->getMessage());
+var_dump($e->getCode());
+var_dump($e->getSeverity());
+var_dump($e->getFile());
+var_dump($e->getLine());
+var_dump($e->getPrevious()::class);
+
+?>
+--EXPECTF--
+string(3) "bar"
+int(1)
+int(8)
+string(5) "file1"
+int(1)
+string(9) "Exception"
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 207b7813854..446aba4ee4a 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -320,15 +320,24 @@ ZEND_METHOD(Exception, __construct)
if (message) {
ZVAL_STR(&tmp, message);
zend_update_property_ex(base_ce, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
if (code) {
ZVAL_LONG(&tmp, code);
zend_update_property_ex(base_ce, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_CODE), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
if (previous) {
zend_update_property_ex(base_ce, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
}
/* }}} */
@@ -370,32 +379,53 @@ ZEND_METHOD(ErrorException, __construct)
ZVAL_STR_COPY(&tmp, message);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
zval_ptr_dtor(&tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
if (code) {
ZVAL_LONG(&tmp, code);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_CODE), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
if (previous) {
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
ZVAL_LONG(&tmp, severity);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
if (filename) {
ZVAL_STR_COPY(&tmp, filename);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
zval_ptr_dtor(&tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
if (!lineno_is_null) {
ZVAL_LONG(&tmp, lineno);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
} else if (filename) {
ZVAL_LONG(&tmp, 0);
zend_update_property_ex(zend_ce_exception, Z_OBJ_P(object), ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
+ if (UNEXPECTED(EG(exception))) {
+ RETURN_THROWS();
+ }
}
}
/* }}} */