From 3a58f9d19be467c786dd2fa3b9a89a7bc3c18b3e Mon Sep 17 00:00:00 2001 From: ju1ius Date: Tue, 15 Aug 2023 16:21:29 +0200 Subject: [PATCH 1/2] adds test case for internal class property attribute --- ext/zend_test/test.c | 7 ++++++ ext/zend_test/test.stub.php | 6 +++++ ext/zend_test/test_arginfo.h | 23 ++++++++++++++++++- .../tests/attribute-internal-property.phpt | 14 +++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 ext/zend_test/tests/attribute-internal-property.phpt diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index ec82c727650b3..22c4c1340ad6d 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -50,6 +50,7 @@ static zend_class_entry *zend_test_parameter_attribute; static zend_class_entry *zend_test_property_attribute; static zend_class_entry *zend_test_class_with_method_with_parameter_attribute; static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute; +static zend_class_entry *zend_test_class_with_property_attribute; static zend_class_entry *zend_test_forbid_dynamic_call; static zend_class_entry *zend_test_ns_foo_class; static zend_class_entry *zend_test_ns_unlikely_compile_error_class; @@ -1021,6 +1022,12 @@ PHP_MINIT_FUNCTION(zend_test) zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute(); zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute); + zend_test_class_with_property_attribute = register_class_ZendTestClassWithPropertyAttribute(); + { + zend_property_info *prop_info = zend_hash_str_find_ptr(&zend_test_class_with_property_attribute->properties_info, "attributed", sizeof("attributed") - 1); + zend_add_property_attribute(zend_test_class_with_property_attribute, prop_info, zend_test_attribute->name, 0); + } + zend_test_forbid_dynamic_call = register_class_ZendTestForbidDynamicCall(); zend_test_ns_foo_class = register_class_ZendTestNS_Foo(); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index 312ad689b31d4..0dad54739abf9 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -107,6 +107,12 @@ public function override( ): int {} } + class ZendTestClassWithPropertyAttribute { + // this attribute must be added internally in MINIT + #[ZendTestAttribute] + public string $attributed; + } + final class ZendTestForbidDynamicCall { public function call(): void {} public static function callStatic(): void {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index d5546638949b1..1b89d2de24ccc 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b458993ee586284b1e33848313d9ddf61273604e */ + * Stub hash: f2d1e5675f75661048645bedc2e73b7d4894f8dc */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -392,6 +392,11 @@ static const zend_function_entry class_ZendTestChildClassWithMethodWithParameter }; +static const zend_function_entry class_ZendTestClassWithPropertyAttribute_methods[] = { + ZEND_FE_END +}; + + static const zend_function_entry class_ZendTestForbidDynamicCall_methods[] = { ZEND_ME(ZendTestForbidDynamicCall, call, arginfo_class_ZendTestForbidDynamicCall_call, ZEND_ACC_PUBLIC) ZEND_ME(ZendTestForbidDynamicCall, callStatic, arginfo_class_ZendTestForbidDynamicCall_callStatic, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) @@ -725,6 +730,22 @@ static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParamete return class_entry; } +static zend_class_entry *register_class_ZendTestClassWithPropertyAttribute(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "ZendTestClassWithPropertyAttribute", class_ZendTestClassWithPropertyAttribute_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + zval property_attributed_default_value; + ZVAL_UNDEF(&property_attributed_default_value); + zend_string *property_attributed_name = zend_string_init("attributed", sizeof("attributed") - 1, 1); + zend_declare_typed_property(class_entry, property_attributed_name, &property_attributed_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING)); + zend_string_release(property_attributed_name); + + return class_entry; +} + static zend_class_entry *register_class_ZendTestForbidDynamicCall(void) { zend_class_entry ce, *class_entry; diff --git a/ext/zend_test/tests/attribute-internal-property.phpt b/ext/zend_test/tests/attribute-internal-property.phpt new file mode 100644 index 0000000000000..e2a62338fe53b --- /dev/null +++ b/ext/zend_test/tests/attribute-internal-property.phpt @@ -0,0 +1,14 @@ +--TEST-- +Tests attributes on internal class properties. +--EXTENSIONS-- +zend_test +reflection +--FILE-- +getAttributes(ZendTestAttribute::class)[0]; +var_dump($attr->getName()); +?> +--EXPECT-- +string(17) "ZendTestAttribute" From d3531dacb70719df1379df1359e7c5b54e213390 Mon Sep 17 00:00:00 2001 From: ju1ius Date: Tue, 15 Aug 2023 16:26:22 +0200 Subject: [PATCH 2/2] releases property attributes of internal classes --- Zend/zend_opcode.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 0aecde93c95cc..c00f0eafc7e2e 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -447,6 +447,9 @@ ZEND_API void destroy_zend_class(zval *zv) if (prop_info->ce == ce) { zend_string_release(prop_info->name); zend_type_release(prop_info->type, /* persistent */ 1); + if (prop_info->attributes) { + zend_hash_release(prop_info->attributes); + } free(prop_info); } } ZEND_HASH_FOREACH_END();