summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-07-06 21:15:05 +0200
committerNikita Popov <nikic@php.net>2016-07-06 21:15:54 +0200
commitab304579ff046426f281e9a95abea8d611e38e1c (patch)
tree93638cc0b9fc1d49b2c512263edad6a72ec5816f
parent0e8fe163b07147a0343969b15544d1fb3a61ace3 (diff)
downloadphp-git-ab304579ff046426f281e9a95abea8d611e38e1c.tar.gz
Forbid use of array() in nested destructuring
Previously array() was only forbidden on the outermost level.
-rw-r--r--Zend/tests/list_014.phpt11
-rw-r--r--Zend/zend_compile.c9
-rw-r--r--Zend/zend_compile.h4
-rw-r--r--Zend/zend_language_parser.y18
4 files changed, 31 insertions, 11 deletions
diff --git a/Zend/tests/list_014.phpt b/Zend/tests/list_014.phpt
new file mode 100644
index 0000000000..7b77825f39
--- /dev/null
+++ b/Zend/tests/list_014.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Cannot destructure using array(), even if nested
+--FILE--
+<?php
+
+[array($a)] = [array(42)];
+var_dump($a);
+
+?>
+--EXPECTF--
+Fatal error: Cannot assign to array(), use [] instead in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 03ab7d177e..bf1615e8bb 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2757,11 +2757,14 @@ void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int d
static void zend_verify_list_assign_target(zend_ast *var_ast, zend_bool old_style) /* {{{ */ {
if (var_ast->kind == ZEND_AST_ARRAY) {
+ if (var_ast->attr == ZEND_ARRAY_SYNTAX_LONG) {
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot assign to array(), use [] instead");
+ }
if (old_style != var_ast->attr) {
- zend_error(E_COMPILE_ERROR, "Cannot mix [] and list()");
+ zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix [] and list()");
}
} else if (!zend_can_write_to_variable(var_ast)) {
- zend_error(E_COMPILE_ERROR, "Assignments can only happen to writable values");
+ zend_error_noreturn(E_COMPILE_ERROR, "Assignments can only happen to writable values");
}
}
/* }}} */
@@ -6480,7 +6483,7 @@ static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
uint32_t i;
zend_bool is_constant = 1;
- if (ast->attr) {
+ if (ast->attr == ZEND_ARRAY_SYNTAX_LIST) {
zend_error(E_COMPILE_ERROR, "Cannot use list() as standalone expression");
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index d05852e8f7..78ee3ddb5e 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -841,6 +841,10 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
#define ZEND_TYPE_NULLABLE (1<<8)
+#define ZEND_ARRAY_SYNTAX_LIST 1 /* list() */
+#define ZEND_ARRAY_SYNTAX_LONG 2 /* array() */
+#define ZEND_ARRAY_SYNTAX_SHORT 3 /* [] */
+
/* var status for backpatching */
#define BP_VAR_R 0
#define BP_VAR_W 1
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 43cf22bfac..c3f51e3053 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -544,8 +544,8 @@ implements_list:
foreach_variable:
variable { $$ = $1; }
| '&' variable { $$ = zend_ast_create(ZEND_AST_REF, $2); }
- | T_LIST '(' array_pair_list ')' { $3->attr = 1; $$ = $3; }
- | '[' array_pair_list ']' { $$ = $2; }
+ | T_LIST '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LIST; }
+ | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
;
for_statement:
@@ -866,9 +866,9 @@ new_expr:
expr_without_variable:
T_LIST '(' array_pair_list ')' '=' expr
- { $3->attr = 1; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
+ { $3->attr = ZEND_ARRAY_SYNTAX_LIST; $$ = zend_ast_create(ZEND_AST_ASSIGN, $3, $6); }
| '[' array_pair_list ']' '=' expr
- { $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); }
+ { $2->attr = ZEND_ARRAY_SYNTAX_SHORT; $$ = zend_ast_create(ZEND_AST_ASSIGN, $2, $5); }
| variable '=' expr
{ $$ = zend_ast_create(ZEND_AST_ASSIGN, $1, $3); }
| variable '=' '&' variable
@@ -1060,8 +1060,8 @@ ctor_arguments:
dereferencable_scalar:
- T_ARRAY '(' array_pair_list ')' { $$ = $3; }
- | '[' array_pair_list ']' { $$ = $2; }
+ T_ARRAY '(' array_pair_list ')' { $$ = $3; $$->attr = ZEND_ARRAY_SYNTAX_LONG; }
+ | '[' array_pair_list ']' { $$ = $2; $$->attr = ZEND_ARRAY_SYNTAX_SHORT; }
| T_CONSTANT_ENCAPSED_STRING { $$ = $1; }
;
@@ -1209,9 +1209,11 @@ array_pair:
| '&' variable
{ $$ = zend_ast_create_ex(ZEND_AST_ARRAY_ELEM, 1, $2, NULL); }
| expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')'
- { $5->attr = 1; $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
+ { $5->attr = ZEND_ARRAY_SYNTAX_LIST;
+ $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $5, $1); }
| T_LIST '(' array_pair_list ')'
- { $3->attr = 1; $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); }
+ { $3->attr = ZEND_ARRAY_SYNTAX_LIST;
+ $$ = zend_ast_create(ZEND_AST_ARRAY_ELEM, $3, NULL); }
;
encaps_list: