From 08b616e2f5384d03f06feaceb0ea60a773c39949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sat, 31 May 2025 22:31:48 +0200 Subject: [PATCH] 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. --- Zend/tests/exception_027.phpt | 37 ++++++++++++++++++++++++++++++ Zend/tests/exception_028.phpt | 43 +++++++++++++++++++++++++++++++++++ Zend/zend_exceptions.c | 30 ++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 Zend/tests/exception_027.phpt create mode 100644 Zend/tests/exception_028.phpt 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-- +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-- +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(); + } } } /* }}} */