]> granicus.if.org Git - php/commitdiff
Forbid use of array() in nested destructuring
authorNikita Popov <nikic@php.net>
Wed, 6 Jul 2016 19:15:05 +0000 (21:15 +0200)
committerNikita Popov <nikic@php.net>
Wed, 6 Jul 2016 19:15:54 +0000 (21:15 +0200)
Previously array() was only forbidden on the outermost level.

Zend/tests/list_014.phpt [new file with mode: 0644]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

diff --git a/Zend/tests/list_014.phpt b/Zend/tests/list_014.phpt
new file mode 100644 (file)
index 0000000..7b77825
--- /dev/null
@@ -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
index 03ab7d177e6a0ebc0b7317de3f47fbf83571ec36..bf1615e8bb13498f195e5598eb13dceaa1e9e900 100644 (file)
@@ -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");
        }
 
index d05852e8f71144849dfe506c7167d84da8784a28..78ee3ddb5e8433b1a11e843fae245a6ac28b33b1 100644 (file)
@@ -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
index 43cf22bfacc61239c95bc5626fce35171bf19a7f..c3f51e305316346366ae75848ddfb8ea3c39bdab 100644 (file)
@@ -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: