Skip to content

Commit 94d2d1d

Browse files
committed
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
1 parent 4659762 commit 94d2d1d

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GH-22112 (Assertion failure when error handler throws during NaN to bool/string coercion at function entry)
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function ($errno, $errstr) {
7+
throw new Exception($errstr);
8+
});
9+
10+
function take_bool(bool $v) {
11+
echo "take_bool entered\n";
12+
}
13+
14+
function take_string(string $v) {
15+
echo "take_string entered\n";
16+
}
17+
18+
$nan = fdiv(0, 0);
19+
20+
try {
21+
take_bool($nan);
22+
} catch (Exception $e) {
23+
echo "bool: ", $e->getMessage(), "\n";
24+
}
25+
26+
try {
27+
take_string($nan);
28+
} catch (Exception $e) {
29+
echo "string: ", $e->getMessage(), "\n";
30+
}
31+
32+
?>
33+
--EXPECT--
34+
bool: unexpected NAN value was coerced to bool
35+
string: unexpected NAN value was coerced to string

Zend/zend_API.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_bool_weak(const zval *arg, bool *dest
537537
return 0;
538538
}
539539
*dest = zend_is_true(arg);
540+
if (UNEXPECTED(EG(exception))) {
541+
return 0;
542+
}
540543
} else {
541544
return 0;
542545
}
@@ -762,6 +765,9 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **des
762765
return 0;
763766
}
764767
convert_to_string(arg);
768+
if (UNEXPECTED(EG(exception))) {
769+
return 0;
770+
}
765771
*dest = Z_STR_P(arg);
766772
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
767773
zend_object *zobj = Z_OBJ_P(arg);

0 commit comments

Comments
 (0)