diff options
author | Nikita Popov <nikic@php.net> | 2016-07-06 21:15:05 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2016-07-06 21:15:54 +0200 |
commit | ab304579ff046426f281e9a95abea8d611e38e1c (patch) | |
tree | 93638cc0b9fc1d49b2c512263edad6a72ec5816f | |
parent | 0e8fe163b07147a0343969b15544d1fb3a61ace3 (diff) | |
download | php-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.phpt | 11 | ||||
-rw-r--r-- | Zend/zend_compile.c | 9 | ||||
-rw-r--r-- | Zend/zend_compile.h | 4 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 18 |
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: |