Merge branch 'PHP-8.3'

* PHP-8.3:
  Factor out common check for short-circuited ast
  Fix OSS-Fuzz #69765: Yield reference to nullsafe chain
This commit is contained in:
Niels Dossche 2024-06-30 13:38:58 +02:00
commit c97885b3cc
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
2 changed files with 22 additions and 10 deletions

View file

@ -0,0 +1,10 @@
--TEST--
OSS-Fuzz #69765: yield reference to nullsafe chain
--FILE--
<?php
function &test($object) {
yield $object->y?->y;
}
?>
--EXPECTF--
Fatal error: Cannot take reference of a nullsafe chain in %s on line %d

View file

@ -2460,6 +2460,13 @@ static bool zend_ast_is_short_circuited(const zend_ast *ast)
}
}
static void zend_assert_not_short_circuited(const zend_ast *ast)
{
if (zend_ast_is_short_circuited(ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
}
}
/* Mark nodes that are an inner part of a short-circuiting chain.
* We should not perform a "commit" on them, as it will be performed by the outer-most node.
* We do this to avoid passing down an argument in various compile functions. */
@ -3463,9 +3470,8 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
if (!zend_is_variable_or_call(expr_ast)) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot assign reference to non referenceable value");
} else if (zend_ast_is_short_circuited(expr_ast)) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot take reference of a nullsafe chain");
} else {
zend_assert_not_short_circuited(expr_ast);
}
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1);
@ -3507,9 +3513,7 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
}
zend_ensure_writable_variable(target_ast);
if (zend_ast_is_short_circuited(source_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
}
zend_assert_not_short_circuited(source_ast);
if (is_globals_fetch(source_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot acquire reference to $GLOBALS");
}
@ -5543,10 +5547,7 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */
expr_node.op_type = IS_CONST;
ZVAL_NULL(&expr_node.u.constant);
} else if (by_ref && zend_is_variable(expr_ast)) {
if (zend_ast_is_short_circuited(expr_ast)) {
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
}
zend_assert_not_short_circuited(expr_ast);
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1);
} else {
zend_compile_expr(&expr_node, expr_ast);
@ -9936,6 +9937,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
if (value_ast) {
if (returns_by_ref && zend_is_variable(value_ast)) {
zend_assert_not_short_circuited(value_ast);
zend_compile_var(&value_node, value_ast, BP_VAR_W, 1);
} else {
zend_compile_expr(&value_node, value_ast);