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