@@ -6590,8 +6590,9 @@ static bool zend_is_valid_default_value(zend_type type, zval *value)
6590
6590
return 0 ;
6591
6591
}
6592
6592
6593
- static void zend_compile_attributes (HashTable * * attributes , zend_ast * ast , uint32_t offset , uint32_t target ) /* {{{ */
6594
- {
6593
+ static void zend_compile_attributes (
6594
+ HashTable * * attributes , zend_ast * ast , uint32_t offset , uint32_t target , uint32_t promoted
6595
+ ) /* {{{ */ {
6595
6596
zend_attribute * attr ;
6596
6597
zend_internal_attribute * config ;
6597
6598
@@ -6617,8 +6618,20 @@ static void zend_compile_attributes(HashTable **attributes, zend_ast *ast, uint3
6617
6618
}
6618
6619
6619
6620
zend_string * name = zend_resolve_class_name_ast (el -> child [0 ]);
6621
+ zend_string * lcname = zend_string_tolower_ex (name , false);
6620
6622
zend_ast_list * args = el -> child [1 ] ? zend_ast_get_list (el -> child [1 ]) : NULL ;
6621
6623
6624
+ config = zend_internal_attribute_get (lcname );
6625
+ zend_string_release (lcname );
6626
+
6627
+ /* Exclude internal attributes that do not match on promoted properties. */
6628
+ if (config && !(target & (config -> flags & ZEND_ATTRIBUTE_TARGET_ALL ))) {
6629
+ if (promoted & (config -> flags & ZEND_ATTRIBUTE_TARGET_ALL )) {
6630
+ zend_string_release (name );
6631
+ continue ;
6632
+ }
6633
+ }
6634
+
6622
6635
uint32_t flags = (CG (active_op_array )-> fn_flags & ZEND_ACC_STRICT_TYPES )
6623
6636
? ZEND_ATTRIBUTE_STRICT_TYPES : 0 ;
6624
6637
attr = zend_add_attribute (
@@ -6663,31 +6676,33 @@ static void zend_compile_attributes(HashTable **attributes, zend_ast *ast, uint3
6663
6676
}
6664
6677
}
6665
6678
6666
- /* Validate attributes in a secondary loop (needed to detect repeated attributes). */
6667
- ZEND_HASH_PACKED_FOREACH_PTR (* attributes , attr ) {
6668
- if (attr -> offset != offset || NULL == (config = zend_internal_attribute_get (attr -> lcname ))) {
6669
- continue ;
6670
- }
6679
+ if (* attributes != NULL ) {
6680
+ /* Validate attributes in a secondary loop (needed to detect repeated attributes). */
6681
+ ZEND_HASH_PACKED_FOREACH_PTR (* attributes , attr ) {
6682
+ if (attr -> offset != offset || NULL == (config = zend_internal_attribute_get (attr -> lcname ))) {
6683
+ continue ;
6684
+ }
6671
6685
6672
- if (!(target & (config -> flags & ZEND_ATTRIBUTE_TARGET_ALL ))) {
6673
- zend_string * location = zend_get_attribute_target_names (target );
6674
- zend_string * allowed = zend_get_attribute_target_names (config -> flags );
6686
+ if (!(target & (config -> flags & ZEND_ATTRIBUTE_TARGET_ALL ))) {
6687
+ zend_string * location = zend_get_attribute_target_names (target );
6688
+ zend_string * allowed = zend_get_attribute_target_names (config -> flags );
6675
6689
6676
- zend_error_noreturn (E_ERROR , "Attribute \"%s\" cannot target %s (allowed targets: %s)" ,
6677
- ZSTR_VAL (attr -> name ), ZSTR_VAL (location ), ZSTR_VAL (allowed )
6678
- );
6679
- }
6690
+ zend_error_noreturn (E_ERROR , "Attribute \"%s\" cannot target %s (allowed targets: %s)" ,
6691
+ ZSTR_VAL (attr -> name ), ZSTR_VAL (location ), ZSTR_VAL (allowed )
6692
+ );
6693
+ }
6680
6694
6681
- if (!(config -> flags & ZEND_ATTRIBUTE_IS_REPEATABLE )) {
6682
- if (zend_is_attribute_repeated (* attributes , attr )) {
6683
- zend_error_noreturn (E_ERROR , "Attribute \"%s\" must not be repeated" , ZSTR_VAL (attr -> name ));
6695
+ if (!(config -> flags & ZEND_ATTRIBUTE_IS_REPEATABLE )) {
6696
+ if (zend_is_attribute_repeated (* attributes , attr )) {
6697
+ zend_error_noreturn (E_ERROR , "Attribute \"%s\" must not be repeated" , ZSTR_VAL (attr -> name ));
6698
+ }
6684
6699
}
6685
- }
6686
6700
6687
- if (config -> validator != NULL ) {
6688
- config -> validator (attr , target , CG (active_class_entry ));
6689
- }
6690
- } ZEND_HASH_FOREACH_END ();
6701
+ if (config -> validator != NULL ) {
6702
+ config -> validator (attr , target , CG (active_class_entry ));
6703
+ }
6704
+ } ZEND_HASH_FOREACH_END ();
6705
+ }
6691
6706
}
6692
6707
/* }}} */
6693
6708
@@ -6822,7 +6837,10 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
6822
6837
arg_info -> type = (zend_type ) ZEND_TYPE_INIT_NONE (0 );
6823
6838
6824
6839
if (attributes_ast ) {
6825
- zend_compile_attributes (& op_array -> attributes , attributes_ast , i + 1 , ZEND_ATTRIBUTE_TARGET_PARAMETER );
6840
+ zend_compile_attributes (
6841
+ & op_array -> attributes , attributes_ast , i + 1 , ZEND_ATTRIBUTE_TARGET_PARAMETER ,
6842
+ property_flags ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0
6843
+ );
6826
6844
}
6827
6845
6828
6846
if (type_ast ) {
@@ -6928,7 +6946,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
6928
6946
scope , name , & default_value , property_flags | ZEND_ACC_PROMOTED , doc_comment , type );
6929
6947
if (attributes_ast ) {
6930
6948
zend_compile_attributes (
6931
- & prop -> attributes , attributes_ast , 0 , ZEND_ATTRIBUTE_TARGET_PROPERTY );
6949
+ & prop -> attributes , attributes_ast , 0 , ZEND_ATTRIBUTE_TARGET_PROPERTY , ZEND_ATTRIBUTE_TARGET_PARAMETER );
6932
6950
}
6933
6951
}
6934
6952
}
@@ -7365,7 +7383,7 @@ static void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel)
7365
7383
target = ZEND_ATTRIBUTE_TARGET_METHOD ;
7366
7384
}
7367
7385
7368
- zend_compile_attributes (& op_array -> attributes , decl -> child [4 ], 0 , target );
7386
+ zend_compile_attributes (& op_array -> attributes , decl -> child [4 ], 0 , target , 0 );
7369
7387
}
7370
7388
7371
7389
/* Do not leak the class scope into free standing functions, even if they are dynamically
@@ -7547,7 +7565,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f
7547
7565
info = zend_declare_typed_property (ce , name , & value_zv , flags , doc_comment , type );
7548
7566
7549
7567
if (attr_ast ) {
7550
- zend_compile_attributes (& info -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_PROPERTY );
7568
+ zend_compile_attributes (& info -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_PROPERTY , 0 );
7551
7569
}
7552
7570
}
7553
7571
}
@@ -7608,7 +7626,7 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as
7608
7626
c = zend_declare_class_constant_ex (ce , name , & value_zv , flags , doc_comment );
7609
7627
7610
7628
if (attr_ast ) {
7611
- zend_compile_attributes (& c -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_CLASS_CONST );
7629
+ zend_compile_attributes (& c -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_CLASS_CONST , 0 );
7612
7630
}
7613
7631
}
7614
7632
}
@@ -7870,7 +7888,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
7870
7888
CG (active_class_entry ) = ce ;
7871
7889
7872
7890
if (decl -> child [3 ]) {
7873
- zend_compile_attributes (& ce -> attributes , decl -> child [3 ], 0 , ZEND_ATTRIBUTE_TARGET_CLASS );
7891
+ zend_compile_attributes (& ce -> attributes , decl -> child [3 ], 0 , ZEND_ATTRIBUTE_TARGET_CLASS , 0 );
7874
7892
}
7875
7893
7876
7894
if (implements_ast ) {
@@ -8028,7 +8046,7 @@ static void zend_compile_enum_case(zend_ast *ast)
8028
8046
8029
8047
zend_ast * attr_ast = ast -> child [3 ];
8030
8048
if (attr_ast ) {
8031
- zend_compile_attributes (& c -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_CLASS_CONST );
8049
+ zend_compile_attributes (& c -> attributes , attr_ast , 0 , ZEND_ATTRIBUTE_TARGET_CLASS_CONST , 0 );
8032
8050
}
8033
8051
}
8034
8052
0 commit comments