]> granicus.if.org Git - php/commitdiff
Treat attribute argument lists like normal argument lists
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 2 Jul 2020 13:27:45 +0000 (15:27 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 2 Jul 2020 13:27:45 +0000 (15:27 +0200)
Allow trailing comma. Syntactically allow unpacking, but forbid it
during compilation.

The trailing comma test-case is adopted from GH-5796.

Zend/tests/attributes/026_unpack_in_args.phpt [new file with mode: 0644]
Zend/tests/attributes/027_trailing_comma_args.phpt [new file with mode: 0644]
Zend/tests/varSyntax/globalNonSimpleVariableError.phpt
Zend/zend_compile.c
Zend/zend_language_parser.y

diff --git a/Zend/tests/attributes/026_unpack_in_args.phpt b/Zend/tests/attributes/026_unpack_in_args.phpt
new file mode 100644 (file)
index 0000000..04a038d
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Cannot use unpacking in attribute argument list
+--FILE--
+<?php
+
+<<MyAttribute(...[1, 2, 3])>>
+class Foo { }
+
+?>
+--EXPECTF--
+Fatal error: Cannot use unpacking in attribute argument list in %s on line %d
diff --git a/Zend/tests/attributes/027_trailing_comma_args.phpt b/Zend/tests/attributes/027_trailing_comma_args.phpt
new file mode 100644 (file)
index 0000000..c8f6adf
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Trailing comma in attribute argument list
+--FILE--
+<?php
+
+<<MyAttribute(
+       "there",
+       "are",
+       "many",
+       "arguments",
+)>>
+class Foo { }
+
+$ref = new \ReflectionClass(Foo::class);
+$attr = $ref->getAttributes()[0];
+var_dump($attr->getName(), $attr->getArguments());
+
+?>
+--EXPECT--
+string(11) "MyAttribute"
+array(4) {
+  [0]=>
+  string(5) "there"
+  [1]=>
+  string(3) "are"
+  [2]=>
+  string(4) "many"
+  [3]=>
+  string(9) "arguments"
+}
index ed04921f89470ab7444180c266bd7d034636f75b..6847c6f2ea7ab6481d04202274a9fe848b78c29a 100644 (file)
@@ -7,4 +7,4 @@ global $$foo->bar;
 
 ?>
 --EXPECTF--
-Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';' in %s on line %d
+Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ';' or ',' in %s on line %d
index d7bea4ee14a61480532449f7f0a5d54bd7db21b3..7ee7e8e9d32529303f001c4608d9536ba72a2bf2 100644 (file)
@@ -5743,6 +5743,11 @@ static void zend_compile_attributes(HashTable **attributes, zend_ast *ast, uint3
                        ZEND_ASSERT(args->kind == ZEND_AST_ARG_LIST);
 
                        for (j = 0; j < args->children; j++) {
+                               if (args->child[j]->kind == ZEND_AST_UNPACK) {
+                                       zend_error_noreturn(E_COMPILE_ERROR,
+                                               "Cannot use unpacking in attribute argument list");
+                               }
+
                                zend_const_expr_to_zval(&attr->argv[j], args->child[j]);
                        }
                }
index 8ec740a05c47dadbf6dbe4523f76b1cb68c19695..88b159cc6e57717510f0e7db1540bc60c3e362c2 100644 (file)
@@ -260,7 +260,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
 %type <ast> identifier type_expr_without_static union_type_without_static
 %type <ast> inline_function union_type
 %type <ast> attributed_statement attributed_class_statement attributed_parameter
-%type <ast> attribute_arguments attribute_decl attribute attributes
+%type <ast> attribute_decl attribute attributes
 
 %type <num> returns_ref function fn is_reference is_variadic variable_modifiers
 %type <num> method_modifiers non_empty_member_modifiers member_modifier optional_visibility_modifier
@@ -317,20 +317,11 @@ name:
        |       T_NS_SEPARATOR namespace_name                           { $$ = $2; $$->attr = ZEND_NAME_FQ; }
 ;
 
-attribute_arguments:
-               expr
-                       { $$ = zend_ast_create_list(1, ZEND_AST_ARG_LIST, $1); }
-       |       attribute_arguments ',' expr
-                       { $$ = zend_ast_list_add($1, $3); }
-;
-
 attribute_decl:
                class_name
                        { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL); }
-       |       class_name '(' ')'
-                       { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, NULL); }
-       |       class_name '(' attribute_arguments ')'
-                       { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $3); }
+       |       class_name argument_list
+                       { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $2); }
 ;
 
 attribute: