Commit b8ff8d64ac5 for php.net
commit b8ff8d64ac5af53af0ceca5e991c2fc9dc73f04b
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sun May 24 20:14:51 2026 -0400
Fix GH-22112: assertion when error handler throws during NaN coercion
zend_parse_arg_bool_weak and zend_parse_arg_str_weak could return
success with EG(exception) already set, because zend_is_true and
convert_to_string emit the NaN coercion warning without checking
whether the user error handler threw. Recv-arg verification for a
userland function then took the no-check ZEND_VM_NEXT_OPCODE branch,
aborting on ZEND_ASSERT(!EG(exception)). Mirror the existing check in
zend_parse_arg_long_weak and propagate failure when the warning leaves
an exception pending.
Fixes GH-22112
Closes GH-22114
diff --git a/NEWS b/NEWS
index f127593dbe0..5e480287f24 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP NEWS
- Core:
. Fixed bug GH-22280 (Incorrect compile error for goto to label preceding
try/finally block). (Pratik Bhujel)
+ . Fixed bug GH-22112 (Assertion when error handler throws during NaN to
+ bool/string coercion). (iliaal)
- BCMath:
. Fixed issues with oversized allocations and signed overflow in bcround()
diff --git a/Zend/tests/type_coercion/gh22112.phpt b/Zend/tests/type_coercion/gh22112.phpt
new file mode 100644
index 00000000000..84fdc393a82
--- /dev/null
+++ b/Zend/tests/type_coercion/gh22112.phpt
@@ -0,0 +1,35 @@
+--TEST--
+GH-22112 (Assertion failure when error handler throws during NaN to bool/string coercion at function entry)
+--FILE--
+<?php
+
+set_error_handler(function ($errno, $errstr) {
+ throw new Exception($errstr);
+});
+
+function take_bool(bool $v) {
+ echo "take_bool entered\n";
+}
+
+function take_string(string $v) {
+ echo "take_string entered\n";
+}
+
+$nan = fdiv(0, 0);
+
+try {
+ take_bool($nan);
+} catch (Exception $e) {
+ echo "bool: ", $e->getMessage(), "\n";
+}
+
+try {
+ take_string($nan);
+} catch (Exception $e) {
+ echo "string: ", $e->getMessage(), "\n";
+}
+
+?>
+--EXPECT--
+bool: unexpected NAN value was coerced to bool
+string: unexpected NAN value was coerced to string
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 538c02f0395..e874c4a5bbd 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -537,6 +537,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest
return 0;
}
*dest = zend_is_true(arg);
+ if (UNEXPECTED(EG(exception))) {
+ return 0;
+ }
} else {
return 0;
}
@@ -762,6 +765,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **des
return 0;
}
convert_to_string(arg);
+ if (UNEXPECTED(EG(exception))) {
+ return 0;
+ }
*dest = Z_STR_P(arg);
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
zend_object *zobj = Z_OBJ_P(arg);