From 205bd8ed0a08de72e1cdd35b03b0bb5a7b4b371e Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 13 Apr 2020 16:49:47 +0200 Subject: [PATCH 1/5] Add PhpCompilerAttribute and PhpAttribute classes. --- .../tests/attributes/compiler_attributes.phpt | 15 +++++++ Zend/tests/attributes/rfcexample.phpt | 40 +++++++++++++++++++ Zend/zend_default_classes.c | 23 +++++++++++ 3 files changed, 78 insertions(+) create mode 100644 Zend/tests/attributes/compiler_attributes.phpt create mode 100644 Zend/tests/attributes/rfcexample.phpt diff --git a/Zend/tests/attributes/compiler_attributes.phpt b/Zend/tests/attributes/compiler_attributes.phpt new file mode 100644 index 0000000000000..de4849ca19d9e --- /dev/null +++ b/Zend/tests/attributes/compiler_attributes.phpt @@ -0,0 +1,15 @@ +--TEST-- +attributes: Add PhpCompilerAttribute +--FILE-- +> +class Foo +{ +} + +$ref = new ReflectionClass(Foo::class); +var_dump($ref->getAttributes()[0]->getAsObject()); +--EXPECTF-- +object(PhpCompilerAttribute)#3 (0) { +} diff --git a/Zend/tests/attributes/rfcexample.phpt b/Zend/tests/attributes/rfcexample.phpt new file mode 100644 index 0000000000000..3c18785f7d526 --- /dev/null +++ b/Zend/tests/attributes/rfcexample.phpt @@ -0,0 +1,40 @@ +--TEST-- +Attributes: RFC Example +--FILE-- +> + class SingleArgument { + public $argumentValue; + + public function __construct($argumentValue) { + $this->argumentValue = $argumentValue; + } + } +} + +namespace { + use My\Attributes\SingleArgument; + + <> + class Foo { + } + + $reflectionClass = new \ReflectionClass(Foo::class); + $attributes = $reflectionClass->getAttributes(); + + var_dump($attributes[0]->getName()); + var_dump($attributes[0]->getArguments()); + var_dump($attributes[0]->getAsObject()); +} +--EXPECTF-- +string(28) "My\Attributes\SingleArgument" +array(1) { + [0]=> + string(11) "Hello World" +} +object(My\Attributes\SingleArgument)#3 (1) { + ["argumentValue"]=> + string(11) "Hello World" +} diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 2c42763f0c5e5..22cbc86fb73eb 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -26,6 +26,28 @@ #include "zend_generators.h" #include "zend_weakrefs.h" +zend_class_entry *zend_ce_php_attribute; +zend_class_entry *zend_ce_php_compiler_attribute; + +static void zend_register_attribute_ce(void) +{ + zend_class_entry ce; + + INIT_CLASS_ENTRY(ce, "PhpAttribute", NULL); + zend_ce_php_attribute = zend_register_internal_class(&ce); + zend_ce_php_attribute->ce_flags |= ZEND_ACC_FINAL; + + //zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0); + //zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1); + + INIT_CLASS_ENTRY(ce, "PhpCompilerAttribute", NULL); + zend_ce_php_compiler_attribute = zend_register_internal_class(&ce); + zend_ce_php_compiler_attribute->ce_flags |= ZEND_ACC_FINAL; + + //zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0); + //zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1); +} + ZEND_API void zend_register_default_classes(void) { zend_register_interfaces(); @@ -34,4 +56,5 @@ ZEND_API void zend_register_default_classes(void) zend_register_closure_ce(); zend_register_generator_ce(); zend_register_weakref_ce(); + zend_register_attribute_ce(); } From 13e53adb96baf2002a740cc35594bc634464f404 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 13 Apr 2020 18:09:50 +0200 Subject: [PATCH 2/5] Add very simple compiler attribute validation for now (no constant ast evaluation). --- .../tests/attributes/compiler_attributes.phpt | 3 +-- Zend/zend_attributes.h | 16 ++++++++++++++ Zend/zend_compile.c | 11 ++++++++++ Zend/zend_default_classes.c | 22 ++++++++++++++----- 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 Zend/zend_attributes.h diff --git a/Zend/tests/attributes/compiler_attributes.phpt b/Zend/tests/attributes/compiler_attributes.phpt index de4849ca19d9e..437c292b67dee 100644 --- a/Zend/tests/attributes/compiler_attributes.phpt +++ b/Zend/tests/attributes/compiler_attributes.phpt @@ -11,5 +11,4 @@ class Foo $ref = new ReflectionClass(Foo::class); var_dump($ref->getAttributes()[0]->getAsObject()); --EXPECTF-- -object(PhpCompilerAttribute)#3 (0) { -} +Fatal error: The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead in %s diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h new file mode 100644 index 0000000000000..15f02a7544c57 --- /dev/null +++ b/Zend/zend_attributes.h @@ -0,0 +1,16 @@ +#ifndef ZEND_ATTRIBUTES_H +#define ZEND_ATTRIBUTES_H + +zend_class_entry *zend_ce_php_attribute; +zend_class_entry *zend_ce_php_compiler_attribute; + +typedef void (*zend_attributes_internal_validator)(zval *attribute); +HashTable zend_attributes_internal_validators; + +static void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator) +{ + zend_string *attribute_name = zend_string_tolower_ex(ce->name, 1); + + zend_hash_update_mem(&zend_attributes_internal_validators, attribute_name, validator, sizeof(zend_attributes_internal_validator)); +} +#endif diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e48e68b67bb6b..3f5bb06727ba1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -20,6 +20,7 @@ #include #include "zend.h" +#include "zend_attributes.h" #include "zend_compile.h" #include "zend_constants.h" #include "zend_llist.h" @@ -5750,6 +5751,8 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */ uint32_t i; zval tmp; + zend_attributes_internal_validator *validator = NULL; + zend_attributes_internal_validator cb; ZVAL_NULL(&tmp); @@ -5770,6 +5773,14 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */ name = zend_string_tolower(Z_STR_P(zend_hash_index_find(Z_ARRVAL(a), 0))); x = zend_hash_find(attr, name); + // validate internal attribute + validator = (zend_attributes_internal_validator*)zend_hash_find_ptr(&zend_attributes_internal_validators, name); + + if (validator != NULL) { + cb = *validator; + cb(&a); + } + if (x) { ZEND_ASSERT(Z_TYPE_P(x) == IS_ARRAY); diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 22cbc86fb73eb..70b0c905c98d6 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -19,6 +19,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_attributes.h" #include "zend_builtin_functions.h" #include "zend_interfaces.h" #include "zend_exceptions.h" @@ -26,26 +27,35 @@ #include "zend_generators.h" #include "zend_weakrefs.h" -zend_class_entry *zend_ce_php_attribute; -zend_class_entry *zend_ce_php_compiler_attribute; +void zend_attribute_validate_phpattribute(zval *attribute) +{ +} + +void zend_attribute_validate_phpcompilerattribute(zval *attribute) +{ + zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead"); +} static void zend_register_attribute_ce(void) { + zend_hash_init(&zend_attributes_internal_validators, 8, NULL, NULL, 1); + zend_class_entry ce; + zend_attributes_internal_validator cb; INIT_CLASS_ENTRY(ce, "PhpAttribute", NULL); zend_ce_php_attribute = zend_register_internal_class(&ce); zend_ce_php_attribute->ce_flags |= ZEND_ACC_FINAL; - //zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0); - //zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1); + cb = zend_attribute_validate_phpattribute; + zend_compiler_attribute_register(zend_ce_php_attribute, &cb); INIT_CLASS_ENTRY(ce, "PhpCompilerAttribute", NULL); zend_ce_php_compiler_attribute = zend_register_internal_class(&ce); zend_ce_php_compiler_attribute->ce_flags |= ZEND_ACC_FINAL; - //zend_hash_init_ex(zend_ce_php_attribute->attributes, 8, NULL, NULL, 1, 0); - //zend_hash_str_add_empty_element(zend_ce_php_attribute->attributes, "phpattribute", sizeof("phpattribute")-1); + cb = zend_attribute_validate_phpcompilerattribute; + zend_compiler_attribute_register(zend_ce_php_compiler_attribute, &cb); } ZEND_API void zend_register_default_classes(void) From db7f5fce4eac6ba9e4881a8670bd40e58d772bbf Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 13 Apr 2020 18:26:08 +0200 Subject: [PATCH 3/5] Validate that class attributes are PhpAttribute or PhpCompilerAttribute. --- Zend/tests/attributes/rfcexample.phpt | 1 + ext/reflection/php_reflection.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/Zend/tests/attributes/rfcexample.phpt b/Zend/tests/attributes/rfcexample.phpt index 3c18785f7d526..8251eee80af2b 100644 --- a/Zend/tests/attributes/rfcexample.phpt +++ b/Zend/tests/attributes/rfcexample.phpt @@ -3,6 +3,7 @@ Attributes: RFC Example --FILE-- > class SingleArgument { diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 0d04e535acb6f..dce031c976451 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -32,6 +32,7 @@ #include "zend.h" #include "zend_API.h" #include "zend_ast.h" +#include "zend_attributes.h" #include "zend_exceptions.h" #include "zend_operators.h" #include "zend_constants.h" @@ -6673,6 +6674,20 @@ ZEND_METHOD(reflection_attribute, getAsObject) RETURN_THROWS(); } + zend_string *lower_name = zend_string_tolower_ex(ce->name, 1); + + if (ce->type == ZEND_USER_CLASS && ce->info.user.attributes && zend_hash_str_exists(ce->info.user.attributes, "phpattribute", sizeof("phpattribute")-1) == 0) { + zend_string_release(lower_name); + zend_throw_error(NULL, "Attempting to use class '%s' as attribute that does not have <>.", ZSTR_VAL(attr->name)); + RETURN_THROWS(); + } else if (ce->type == ZEND_INTERNAL_CLASS && zend_hash_exists(&zend_attributes_internal_validators, lower_name) == 0) { + zend_string_release(lower_name); + zend_throw_error(NULL, "Attempting to use internal class '%s' as attribute that does not have <>.", ZSTR_VAL(attr->name)); + RETURN_THROWS(); + } + + zend_string_release(lower_name); + count = zend_hash_num_elements(Z_ARRVAL(attr->arguments)); if (count) { From 0bb4d66f82b45685eb3f9ac3118a0cae14776fda Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 13 Apr 2020 19:21:24 +0200 Subject: [PATCH 4/5] Move code from zend_default_classes.c to zend_attributes.c --- Zend/zend_attributes.c | 41 +++++++++++++++++++++++++++++++++++++ Zend/zend_attributes.h | 8 ++------ Zend/zend_default_classes.c | 31 ---------------------------- configure.ac | 2 +- win32/build/config.w32 | 2 +- 5 files changed, 45 insertions(+), 39 deletions(-) create mode 100644 Zend/zend_attributes.c diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c new file mode 100644 index 0000000000000..f2f04ee4848d0 --- /dev/null +++ b/Zend/zend_attributes.c @@ -0,0 +1,41 @@ +#include "zend.h" +#include "zend_API.h" +#include "zend_attributes.h" + +void zend_attribute_validate_phpattribute(zval *attribute) +{ +} + +void zend_attribute_validate_phpcompilerattribute(zval *attribute) +{ + zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead"); +} + +void zend_register_attribute_ce(void) +{ + zend_hash_init(&zend_attributes_internal_validators, 8, NULL, NULL, 1); + + zend_class_entry ce; + zend_attributes_internal_validator cb; + + INIT_CLASS_ENTRY(ce, "PhpAttribute", NULL); + zend_ce_php_attribute = zend_register_internal_class(&ce); + zend_ce_php_attribute->ce_flags |= ZEND_ACC_FINAL; + + cb = zend_attribute_validate_phpattribute; + zend_compiler_attribute_register(zend_ce_php_attribute, &cb); + + INIT_CLASS_ENTRY(ce, "PhpCompilerAttribute", NULL); + zend_ce_php_compiler_attribute = zend_register_internal_class(&ce); + zend_ce_php_compiler_attribute->ce_flags |= ZEND_ACC_FINAL; + + cb = zend_attribute_validate_phpcompilerattribute; + zend_compiler_attribute_register(zend_ce_php_compiler_attribute, &cb); +} + +void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator) +{ + zend_string *attribute_name = zend_string_tolower_ex(ce->name, 1); + + zend_hash_update_mem(&zend_attributes_internal_validators, attribute_name, validator, sizeof(zend_attributes_internal_validator)); +} diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index 15f02a7544c57..d47fc657f506b 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -7,10 +7,6 @@ zend_class_entry *zend_ce_php_compiler_attribute; typedef void (*zend_attributes_internal_validator)(zval *attribute); HashTable zend_attributes_internal_validators; -static void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator) -{ - zend_string *attribute_name = zend_string_tolower_ex(ce->name, 1); - - zend_hash_update_mem(&zend_attributes_internal_validators, attribute_name, validator, sizeof(zend_attributes_internal_validator)); -} +void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator); +void zend_register_attribute_ce(void); #endif diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 70b0c905c98d6..63cdf66d580e8 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -27,37 +27,6 @@ #include "zend_generators.h" #include "zend_weakrefs.h" -void zend_attribute_validate_phpattribute(zval *attribute) -{ -} - -void zend_attribute_validate_phpcompilerattribute(zval *attribute) -{ - zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead"); -} - -static void zend_register_attribute_ce(void) -{ - zend_hash_init(&zend_attributes_internal_validators, 8, NULL, NULL, 1); - - zend_class_entry ce; - zend_attributes_internal_validator cb; - - INIT_CLASS_ENTRY(ce, "PhpAttribute", NULL); - zend_ce_php_attribute = zend_register_internal_class(&ce); - zend_ce_php_attribute->ce_flags |= ZEND_ACC_FINAL; - - cb = zend_attribute_validate_phpattribute; - zend_compiler_attribute_register(zend_ce_php_attribute, &cb); - - INIT_CLASS_ENTRY(ce, "PhpCompilerAttribute", NULL); - zend_ce_php_compiler_attribute = zend_register_internal_class(&ce); - zend_ce_php_compiler_attribute->ce_flags |= ZEND_ACC_FINAL; - - cb = zend_attribute_validate_phpcompilerattribute; - zend_compiler_attribute_register(zend_ce_php_compiler_attribute, &cb); -} - ZEND_API void zend_register_default_classes(void) { zend_register_interfaces(); diff --git a/configure.ac b/configure.ac index 651fc9c194fb0..c5eb05dfe33ea 100644 --- a/configure.ac +++ b/configure.ac @@ -1459,7 +1459,7 @@ PHP_ADD_SOURCES(Zend, \ zend_execute_API.c zend_highlight.c zend_llist.c \ zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \ zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \ - zend_list.c zend_builtin_functions.c \ + zend_list.c zend_builtin_functions.c zend_attributes.c \ zend_ini.c zend_sort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 62dbeb40d9b08..d90b757a798b5 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -230,7 +230,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_execute_API.c zend_highlight.c \ zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \ zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \ - zend_hash.c zend_list.c zend_builtin_functions.c \ + zend_hash.c zend_list.c zend_builtin_functions.c zend_attributes.c \ zend_ini.c zend_sort.c zend_multibyte.c zend_ts_hash.c \ zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \ zend_object_handlers.c zend_objects_API.c \ From 72aea5a10879bb3fe6260842395ca0e1686f9f66 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 13 Apr 2020 19:30:27 +0200 Subject: [PATCH 5/5] Allow internal compiler attribute validators to check for attributed target. --- Zend/tests/attributes/wrong_atttribution.phpt | 9 +++++++++ Zend/zend_attributes.c | 7 +++++-- Zend/zend_attributes.h | 10 +++++++++- Zend/zend_compile.c | 18 +++++++++++------- 4 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 Zend/tests/attributes/wrong_atttribution.phpt diff --git a/Zend/tests/attributes/wrong_atttribution.phpt b/Zend/tests/attributes/wrong_atttribution.phpt new file mode 100644 index 0000000000000..dcb0b6b51d0fe --- /dev/null +++ b/Zend/tests/attributes/wrong_atttribution.phpt @@ -0,0 +1,9 @@ +--TEST-- +Attributes: Prevent PhpAttribute on non classes +--FILE-- +> +function foo() {} +--EXPECTF-- +Fatal error: Only classes can be marked with <> in %s diff --git a/Zend/zend_attributes.c b/Zend/zend_attributes.c index f2f04ee4848d0..62a62eaae4059 100644 --- a/Zend/zend_attributes.c +++ b/Zend/zend_attributes.c @@ -2,11 +2,14 @@ #include "zend_API.h" #include "zend_attributes.h" -void zend_attribute_validate_phpattribute(zval *attribute) +void zend_attribute_validate_phpattribute(zval *attribute, int target) { + if (target != ZEND_ATTRIBUTE_TARGET_CLASS) { + zend_error(E_COMPILE_ERROR, "Only classes can be marked with <>"); + } } -void zend_attribute_validate_phpcompilerattribute(zval *attribute) +void zend_attribute_validate_phpcompilerattribute(zval *attribute, int target) { zend_error(E_COMPILE_ERROR, "The PhpCompilerAttribute can only be used by internal classes, use PhpAttribute instead"); } diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index d47fc657f506b..2312e3c13ebf0 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -1,10 +1,18 @@ #ifndef ZEND_ATTRIBUTES_H #define ZEND_ATTRIBUTES_H +#define ZEND_ATTRIBUTE_TARGET_CLASS 1 +#define ZEND_ATTRIBUTE_TARGET_FUNCTION 2 +#define ZEND_ATTRIBUTE_TARGET_METHOD 4 +#define ZEND_ATTRIBUTE_TARGET_PROPERTY 8 +#define ZEND_ATTRIBUTE_TARGET_CLASS_CONST 16 +#define ZEND_ATTRIBUTE_TARGET_PARAMETER 32 +#define ZEND_ATTRIBUTE_TARGET_ALL 63 + zend_class_entry *zend_ce_php_attribute; zend_class_entry *zend_ce_php_compiler_attribute; -typedef void (*zend_attributes_internal_validator)(zval *attribute); +typedef void (*zend_attributes_internal_validator)(zval *attribute, int target); HashTable zend_attributes_internal_validators; void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator *validator); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 3f5bb06727ba1..00c0c99dbf601 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5743,7 +5743,7 @@ static void zend_compile_attribute(zval *v, zend_ast *ast) /* {{{ */ } /* }}} */ -static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */ +static HashTable *zend_compile_attributes(zend_ast *ast, int target) /* {{{ */ { HashTable *attr; @@ -5778,7 +5778,7 @@ static HashTable *zend_compile_attributes(zend_ast *ast) /* {{{ */ if (validator != NULL) { cb = *validator; - cb(&a); + cb(&a, target); } if (x) { @@ -5921,7 +5921,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall zend_hash_init(op_array->attributes, 8, NULL, ZVAL_PTR_DTOR, 0); } - ZVAL_ARR(&attr, zend_compile_attributes(attributes_ast)); + ZVAL_ARR(&attr, zend_compile_attributes(attributes_ast, ZEND_ATTRIBUTE_TARGET_PARAMETER)); zend_hash_index_add(op_array->attributes, i, &attr); } @@ -6381,7 +6381,11 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /* op_array->doc_comment = zend_string_copy(decl->doc_comment); } if (decl->attributes) { - op_array->attributes = zend_compile_attributes(decl->attributes); + int target = ZEND_ATTRIBUTE_TARGET_FUNCTION; + if (is_method) { + target = ZEND_ATTRIBUTE_TARGET_METHOD; + } + op_array->attributes = zend_compile_attributes(decl->attributes, target); } if (decl->kind == ZEND_AST_CLOSURE || decl->kind == ZEND_AST_ARROW_FUNC) { op_array->fn_flags |= ZEND_ACC_CLOSURE; @@ -6555,7 +6559,7 @@ void zend_compile_prop_group(zend_ast *list) /* {{{ */ zend_ast *type_ast = list->child[0]; zend_ast *prop_ast = list->child[1]; - attributes = list->child[2] ? zend_compile_attributes(list->child[2]) : NULL; + attributes = list->child[2] ? zend_compile_attributes(list->child[2], ZEND_ATTRIBUTE_TARGET_PROPERTY) : NULL; zend_compile_prop_decl(prop_ast, type_ast, list->attr, attributes); @@ -6589,7 +6593,7 @@ void zend_compile_class_const_decl(zend_ast *ast, zend_ast *attr_ast) /* {{{ */ return; } - attributes = attr_ast ? zend_compile_attributes(attr_ast) : NULL; + attributes = attr_ast ? zend_compile_attributes(attr_ast, ZEND_ATTRIBUTE_TARGET_CLASS_CONST) : NULL; for (i = 0; i < list->children; ++i) { zend_ast *const_ast = list->child[i]; @@ -6820,7 +6824,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */ ce->info.user.doc_comment = zend_string_copy(decl->doc_comment); } if (decl->attributes) { - ce->info.user.attributes = zend_compile_attributes(decl->attributes); + ce->info.user.attributes = zend_compile_attributes(decl->attributes, ZEND_ATTRIBUTE_TARGET_CLASS); } if (UNEXPECTED((decl->flags & ZEND_ACC_ANON_CLASS))) {