The VM assumes that an exception must be handled when the AST evaluation
returns FAILURE. However, the comparison functions always return SUCCESS
even if an exception happened. This can be fixed in
zend_ast_evaluate_inner() or we can make is_smaller_function() etc check
for the exception. I chose the former to avoid impact or API breaks.
Perhaps in the future the comparison functions should either return void
or return whether an exception happened, as to be not misleading.

Closes GH-18589.
This commit is contained in:
Niels Dossche 2025-05-18 14:59:27 +02:00
parent 46ac878f6a
commit 98cb17f4fd
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 23 additions and 1 deletions

1
NEWS
View file

@ -8,6 +8,7 @@ PHP NEWS
. Partially fixed GH-18572 (nested object comparisons leading to stack overflow).
(David Carlier)
. Fixed OSS-Fuzz #417078295. (nielsdos)
. Fixed OSS-Fuzz #418106144. (nielsdos)
- Curl:
. Fixed GH-18460 (curl_easy_setopt with CURLOPT_USERPWD/CURLOPT_USERNAME/

View file

@ -0,0 +1,20 @@
--TEST--
OSS-Fuzz #418106144
--FILE--
<?php
class Foo {
function __toString(){}
}
function test($y=new Foo>''){
var_dump();
}
try {
test();
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Foo::__toString(): Return value must be of type string, none returned

View file

@ -564,9 +564,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
/* op1 > op2 is the same as op2 < op1 */
binary_op_type op = ast->kind == ZEND_AST_GREATER
? is_smaller_function : is_smaller_or_equal_function;
ret = op(result, &op2, &op1);
op(result, &op2, &op1);
zval_ptr_dtor_nogc(&op1);
zval_ptr_dtor_nogc(&op2);
ret = EG(exception) ? FAILURE : SUCCESS;
}
break;
case ZEND_AST_UNARY_OP: