Skip to content

Commit 015b519

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Factor out common check for short-circuited ast Fix OSS-Fuzz #69765: Yield reference to nullsafe chain
2 parents 1b71a9e + 8fd0956 commit 015b519

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PHP NEWS
88
. Fixed bug GH-14626 (Fix is_zend_ptr() for huge blocks). (Arnaud)
99
. Fixed bug GH-14590 (Memory leak in FPM test gh13563-conf-bool-env.phpt.
1010
(nielsdos)
11+
. Fixed OSS-Fuzz #69765. (nielsdos)
1112

1213
- Dom:
1314
. Fixed bug GH-14702 (DOMDocument::xinclude() crash). (nielsdos)

Zend/tests/oss-fuzz-69765.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
OSS-Fuzz #69765: yield reference to nullsafe chain
3+
--FILE--
4+
<?php
5+
function &test($object) {
6+
yield $object->y?->y;
7+
}
8+
?>
9+
--EXPECTF--
10+
Fatal error: Cannot take reference of a nullsafe chain in %s on line %d

Zend/zend_compile.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,6 +2438,13 @@ static bool zend_ast_is_short_circuited(const zend_ast *ast)
24382438
}
24392439
}
24402440

2441+
static void zend_assert_not_short_circuited(const zend_ast *ast)
2442+
{
2443+
if (zend_ast_is_short_circuited(ast)) {
2444+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
2445+
}
2446+
}
2447+
24412448
/* Mark nodes that are an inner part of a short-circuiting chain.
24422449
* We should not perform a "commit" on them, as it will be performed by the outer-most node.
24432450
* We do this to avoid passing down an argument in various compile functions. */
@@ -3426,9 +3433,8 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
34263433
if (!zend_is_variable_or_call(expr_ast)) {
34273434
zend_error_noreturn(E_COMPILE_ERROR,
34283435
"Cannot assign reference to non referenceable value");
3429-
} else if (zend_ast_is_short_circuited(expr_ast)) {
3430-
zend_error_noreturn(E_COMPILE_ERROR,
3431-
"Cannot take reference of a nullsafe chain");
3436+
} else {
3437+
zend_assert_not_short_circuited(expr_ast);
34323438
}
34333439

34343440
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1);
@@ -3470,9 +3476,7 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
34703476
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
34713477
}
34723478
zend_ensure_writable_variable(target_ast);
3473-
if (zend_ast_is_short_circuited(source_ast)) {
3474-
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
3475-
}
3479+
zend_assert_not_short_circuited(source_ast);
34763480
if (is_globals_fetch(source_ast)) {
34773481
zend_error_noreturn(E_COMPILE_ERROR, "Cannot acquire reference to $GLOBALS");
34783482
}
@@ -5173,10 +5177,7 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */
51735177
expr_node.op_type = IS_CONST;
51745178
ZVAL_NULL(&expr_node.u.constant);
51755179
} else if (by_ref && zend_is_variable(expr_ast)) {
5176-
if (zend_ast_is_short_circuited(expr_ast)) {
5177-
zend_error_noreturn(E_COMPILE_ERROR, "Cannot take reference of a nullsafe chain");
5178-
}
5179-
5180+
zend_assert_not_short_circuited(expr_ast);
51805181
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, 1);
51815182
} else {
51825183
zend_compile_expr(&expr_node, expr_ast);
@@ -9512,6 +9513,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
95129513

95139514
if (value_ast) {
95149515
if (returns_by_ref && zend_is_variable(value_ast)) {
9516+
zend_assert_not_short_circuited(value_ast);
95159517
zend_compile_var(&value_node, value_ast, BP_VAR_W, 1);
95169518
} else {
95179519
zend_compile_expr(&value_node, value_ast);

0 commit comments

Comments
 (0)