Skip to content

Commit 7f3ebaa

Browse files
committed
Fix list() assignment in array literals
Fixes GH-11320
1 parent adb3d52 commit 7f3ebaa

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

Zend/tests/gh11320_1.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
GH-11320: Array literals can contain list() assignments
3+
--FILE--
4+
<?php
5+
$index = 1;
6+
function getList() { return [2, 3]; }
7+
var_dump([$index => list($x, $y) = getList()]);
8+
var_dump([$index => [$x, $y] = getList()]);
9+
?>
10+
--EXPECT--
11+
array(1) {
12+
[1]=>
13+
array(2) {
14+
[0]=>
15+
int(2)
16+
[1]=>
17+
int(3)
18+
}
19+
}
20+
array(1) {
21+
[1]=>
22+
array(2) {
23+
[0]=>
24+
int(2)
25+
[1]=>
26+
int(3)
27+
}
28+
}

Zend/tests/gh11320_2.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
GH-11320: list() expressions can contain magic constants
3+
--FILE--
4+
<?php
5+
[list(__FILE__ => $foo) = [__FILE__ => 'foo']];
6+
var_dump($foo);
7+
[[__FILE__ => $foo] = [__FILE__ => 'foo']];
8+
var_dump($foo);
9+
?>
10+
--EXPECT--
11+
string(3) "foo"
12+
string(3) "foo"

Zend/tests/gh11320_3.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
--TEST--
2+
GH-11320: list() must not appear as a standalone array element
3+
--FILE--
4+
<?php
5+
[list($a)];
6+
?>
7+
--EXPECTF--
8+
Fatal error: Cannot use list() as standalone expression in %s on line %d

Zend/zend_compile.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10617,10 +10617,23 @@ static void zend_eval_const_expr_inner(zend_ast **ast_ptr, void *ctx) /* {{{ */
1061710617
* differenciate between literal class names and expressions that evaluate to strings. Strings
1061810618
* are not actually allowed in ::class expressions.
1061910619
*
10620-
* ZEND_AST_COALESCE and ZEND_AST_CONDITIONAL will manually evaluate only the children for the
10621-
* taken paths. */
10622-
if (ast->kind != ZEND_AST_CLASS_NAME && ast->kind != ZEND_AST_COALESCE && ast->kind != ZEND_AST_CONDITIONAL) {
10623-
zend_ast_apply(ast, zend_eval_const_expr_inner, ctx);
10620+
* ZEND_AST_ARRAY, ZEND_AST_COALESCE and ZEND_AST_CONDITIONAL will manually evaluate only the
10621+
* children for the taken paths.
10622+
*
10623+
* The lhs of ZEND_AST_ASSIGN can contain list() expressions which should not be evaluated. Skip
10624+
* assignments entirely. They can't appear in constant expressions, and if inside arrays they
10625+
* will be re-evaluated. */
10626+
switch (ast->kind) {
10627+
case ZEND_AST_ARRAY:
10628+
case ZEND_AST_ASSIGN:
10629+
case ZEND_AST_CLASS_NAME:
10630+
case ZEND_AST_COALESCE:
10631+
case ZEND_AST_CONDITIONAL:
10632+
break;
10633+
default:
10634+
if (!zend_ast_is_special(ast)) {
10635+
zend_ast_apply(ast, zend_eval_const_expr_inner, ctx);
10636+
}
1062410637
}
1062510638

1062610639
switch (ast->kind) {

0 commit comments

Comments
 (0)