Skip to content

Commit ab30457

Browse files
committed
Forbid use of array() in nested destructuring
Previously array() was only forbidden on the outermost level.
1 parent 0e8fe16 commit ab30457

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

Zend/tests/list_014.phpt

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Cannot destructure using array(), even if nested
3+
--FILE--
4+
<?php
5+
6+
[array($a)] = [array(42)];
7+
var_dump($a);
8+
9+
?>
10+
--EXPECTF--
11+
Fatal error: Cannot assign to array(), use [] instead in %s on line %d

Zend/zend_compile.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -2757,11 +2757,14 @@ void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int d
27572757

27582758
static void zend_verify_list_assign_target(zend_ast *var_ast, zend_bool old_style) /* {{{ */ {
27592759
if (var_ast->kind == ZEND_AST_ARRAY) {
2760+
if (var_ast->attr == ZEND_ARRAY_SYNTAX_LONG) {
2761+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot assign to array(), use [] instead");
2762+
}
27602763
if (old_style != var_ast->attr) {
2761-
zend_error(E_COMPILE_ERROR, "Cannot mix [] and list()");
2764+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix [] and list()");
27622765
}
27632766
} else if (!zend_can_write_to_variable(var_ast)) {
2764-
zend_error(E_COMPILE_ERROR, "Assignments can only happen to writable values");
2767+
zend_error_noreturn(E_COMPILE_ERROR, "Assignments can only happen to writable values");
27652768
}
27662769
}
27672770
/* }}} */
@@ -6480,7 +6483,7 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
64806483
uint32_t i;
64816484
zend_bool is_constant = 1;
64826485

6483-
if (ast->attr) {
6486+
if (ast->attr == ZEND_ARRAY_SYNTAX_LIST) {
64846487
zend_error(E_COMPILE_ERROR, "Cannot use list() as standalone expression");
64856488
}
64866489

Zend/zend_compile.h

+4
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,10 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
841841

842842
#define ZEND_TYPE_NULLABLE (1<<8)
843843

844+
#define ZEND_ARRAY_SYNTAX_LIST 1 /* list() */
845+
#define ZEND_ARRAY_SYNTAX_LONG 2 /* array() */
846+
#define ZEND_ARRAY_SYNTAX_SHORT 3 /* [] */
847+
844848
/* var status for backpatching */
845849
#define BP_VAR_R 0
846850
#define BP_VAR_W 1

Zend/zend_language_parser.y

+10-8
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,8 @@ implements_list:
544544
foreach_variable:
545545
variable { $$ = $1; }
546546
| '&' variable { $$ = zend_ast_create(ZEND_AST_REF, $2); }
547-
| T_LIST '(' array_pair_list ')' { $3->attr = 1; $$ = $3; }
548-
| '[' array_pair_list ']' { $$ = $2; }
547+
| T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; }
548+
| '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
549549
;
550550

551551
for_statement:
@@ -866,9 +866,9 @@ new_expr:
866866

867867
expr_without_variable:
868868
T_LIST '(' array_pair_list ')' '=' expr
869-
{ $3->attr = 1; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
869+
{ $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
870870
| '[' array_pair_list ']' '=' expr
871-
{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); }
871+
{ $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); }
872872
| variable '=' expr
873873
{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
874874
| variable '=' '&' variable
@@ -1060,8 +1060,8 @@ ctor_arguments:
10601060

10611061

10621062
dereferencable_scalar:
1063-
T_ARRAY '(' array_pair_list ')' { $$ = $3; }
1064-
| '[' array_pair_list ']' { $$ = $2; }
1063+
T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; }
1064+
| '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
10651065
| T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
10661066
;
10671067

@@ -1209,9 +1209,11 @@ array_pair:
12091209
| '&' variable
12101210
{ $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); }
12111211
| expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')'
1212-
{ $5->attr = 1; $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
1212+
{ $5->attr = ZEND_ARRAY_SYNTAX_LIST;
1213+
$$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
12131214
| T_LIST '(' array_pair_list ')'
1214-
{ $3->attr = 1; $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); }
1215+
{ $3->attr = ZEND_ARRAY_SYNTAX_LIST;
1216+
$$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); }
12151217
;
12161218

12171219
encaps_list:

0 commit comments

Comments
 (0)