Skip to content

Commit fb7b2cf

Browse files
committed
Add tests for function parameter attributes to ext/zend_test
These tests verify the correct workings of the previous fixes: - Parameter attributes for native functions should not leak memory. - Parameter attributes for native functions should behave as expected.
1 parent ec1cb37 commit fb7b2cf

File tree

5 files changed

+444
-1
lines changed

5 files changed

+444
-1
lines changed

ext/zend_test/test.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ static zend_class_entry *zend_test_class;
3737
static zend_class_entry *zend_test_child_class;
3838
static zend_class_entry *zend_test_trait;
3939
static zend_class_entry *zend_test_attribute;
40+
static zend_class_entry *zend_test_parameter_attribute;
41+
static zend_class_entry *zend_test_class_with_method_with_parameter_attribute;
42+
static zend_class_entry *zend_test_child_class_with_method_with_parameter_attribute;
4043
static zend_class_entry *zend_test_ns_foo_class;
4144
static zend_class_entry *zend_test_ns2_foo_class;
4245
static zend_class_entry *zend_test_ns2_ns_foo_class;
@@ -313,6 +316,17 @@ static ZEND_FUNCTION(namespaced_func)
313316
RETURN_TRUE;
314317
}
315318

319+
static ZEND_FUNCTION(zend_test_parameter_with_attribute)
320+
{
321+
zend_string *parameter;
322+
323+
ZEND_PARSE_PARAMETERS_START(1, 1)
324+
Z_PARAM_STR(parameter)
325+
ZEND_PARSE_PARAMETERS_END();
326+
327+
RETURN_LONG(1);
328+
}
329+
316330
static zend_object *zend_test_class_new(zend_class_entry *class_type)
317331
{
318332
zend_object *obj = zend_objects_new(class_type);
@@ -425,6 +439,50 @@ static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method)
425439
ZEND_PARSE_PARAMETERS_NONE();
426440
}
427441

442+
static ZEND_METHOD(ZendTestParameterAttribute, __construct)
443+
{
444+
zend_string *parameter;
445+
446+
ZEND_PARSE_PARAMETERS_START(1, 1)
447+
Z_PARAM_STR(parameter)
448+
ZEND_PARSE_PARAMETERS_END();
449+
450+
ZVAL_STR_COPY(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), parameter);
451+
}
452+
453+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override)
454+
{
455+
zend_string *parameter;
456+
457+
ZEND_PARSE_PARAMETERS_START(1, 1)
458+
Z_PARAM_STR(parameter)
459+
ZEND_PARSE_PARAMETERS_END();
460+
461+
RETURN_LONG(2);
462+
}
463+
464+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override)
465+
{
466+
zend_string *parameter;
467+
468+
ZEND_PARSE_PARAMETERS_START(1, 1)
469+
Z_PARAM_STR(parameter)
470+
ZEND_PARSE_PARAMETERS_END();
471+
472+
RETURN_LONG(3);
473+
}
474+
475+
static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override)
476+
{
477+
zend_string *parameter;
478+
479+
ZEND_PARSE_PARAMETERS_START(1, 1)
480+
Z_PARAM_STR(parameter)
481+
ZEND_PARSE_PARAMETERS_END();
482+
483+
RETURN_LONG(4);
484+
}
485+
428486
PHP_INI_BEGIN()
429487
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
430488
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
@@ -460,6 +518,61 @@ PHP_MINIT_FUNCTION(zend_test)
460518
attr->validator = zend_attribute_validate_zendtestattribute;
461519
}
462520

521+
zend_test_parameter_attribute = register_class_ZendTestParameterAttribute();
522+
zend_internal_attribute_register(zend_test_parameter_attribute, ZEND_ATTRIBUTE_TARGET_PARAMETER);
523+
524+
{
525+
zend_attribute *attr;
526+
527+
attr = zend_add_parameter_attribute(
528+
zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1),
529+
0,
530+
zend_test_parameter_attribute->name,
531+
1
532+
);
533+
534+
ZVAL_PSTRING(&attr->args[0].value, "value1");
535+
}
536+
537+
zend_test_class_with_method_with_parameter_attribute = register_class_ZendTestClassWithMethodWithParameterAttribute();
538+
539+
{
540+
zend_attribute *attr;
541+
542+
attr = zend_add_parameter_attribute(
543+
zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "no_override", sizeof("no_override") - 1),
544+
0,
545+
zend_test_parameter_attribute->name,
546+
1
547+
);
548+
549+
ZVAL_PSTRING(&attr->args[0].value, "value2");
550+
551+
attr = zend_add_parameter_attribute(
552+
zend_hash_str_find_ptr(&zend_test_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
553+
0,
554+
zend_test_parameter_attribute->name,
555+
1
556+
);
557+
558+
ZVAL_PSTRING(&attr->args[0].value, "value3");
559+
}
560+
561+
zend_test_child_class_with_method_with_parameter_attribute = register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_test_class_with_method_with_parameter_attribute);
562+
563+
{
564+
zend_attribute *attr;
565+
566+
attr = zend_add_parameter_attribute(
567+
zend_hash_str_find_ptr(&zend_test_child_class_with_method_with_parameter_attribute->function_table, "override", sizeof("override") - 1),
568+
0,
569+
zend_test_parameter_attribute->name,
570+
1
571+
);
572+
573+
ZVAL_PSTRING(&attr->args[0].value, "value4");
574+
}
575+
463576
zend_test_ns_foo_class = register_class_ZendTestNS_Foo();
464577
zend_test_ns2_foo_class = register_class_ZendTestNS2_Foo();
465578
zend_test_ns2_ns_foo_class = register_class_ZendTestNS2_ZendSubNS_Foo();

ext/zend_test/test.stub.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ final class ZendTestAttribute {
4545

4646
}
4747

48+
final class ZendTestParameterAttribute {
49+
public string $parameter;
50+
51+
public function __construct(string $parameter) {}
52+
}
53+
54+
class ZendTestClassWithMethodWithParameterAttribute {
55+
final public function no_override(string $parameter): int {}
56+
public function override(string $parameter): int {}
57+
}
58+
59+
class ZendTestChildClassWithMethodWithParameterAttribute extends ZendTestClassWithMethodWithParameterAttribute {
60+
public function override(string $parameter): int {}
61+
}
62+
4863
enum ZendTestUnitEnum {
4964
case Foo;
5065
case Bar;
@@ -92,6 +107,8 @@ function zend_weakmap_remove(object $object): bool {}
92107
function zend_weakmap_dump(): array {}
93108

94109
function zend_get_unit_enum(): ZendTestUnitEnum {}
110+
111+
function zend_test_parameter_with_attribute(#[ZendTestParameterAttribute] string $parameter): int {}
95112
}
96113

97114
namespace ZendTestNS {

ext/zend_test/test_arginfo.h

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 7326163f8ce5340c12e74af72d47a8926eb39786 */
2+
* Stub hash: af5d698b35753ac9f852688644d6844ba0914b2b */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
55
ZEND_END_ARG_INFO()
@@ -71,6 +71,10 @@ ZEND_END_ARG_INFO()
7171
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0)
7272
ZEND_END_ARG_INFO()
7373

74+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_parameter_with_attribute, 0, 1, IS_LONG, 0)
75+
ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0)
76+
ZEND_END_ARG_INFO()
77+
7478
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ZendTestNS2_ZendSubNS_namespaced_func, 0, 0, _IS_BOOL, 0)
7579
ZEND_END_ARG_INFO()
7680

@@ -91,6 +95,16 @@ ZEND_END_ARG_INFO()
9195

9296
#define arginfo_class__ZendTestTrait_testMethod arginfo_ZendTestNS2_ZendSubNS_namespaced_func
9397

98+
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZendTestParameterAttribute___construct, 0, 0, 1)
99+
ZEND_ARG_TYPE_INFO(0, parameter, IS_STRING, 0)
100+
ZEND_END_ARG_INFO()
101+
102+
#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override arginfo_zend_test_parameter_with_attribute
103+
104+
#define arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute
105+
106+
#define arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override arginfo_zend_test_parameter_with_attribute
107+
94108
#define arginfo_class_ZendTestNS_Foo_method arginfo_zend_test_void_return
95109

96110
#define arginfo_class_ZendTestNS2_Foo_method arginfo_zend_test_void_return
@@ -116,13 +130,18 @@ static ZEND_FUNCTION(zend_weakmap_attach);
116130
static ZEND_FUNCTION(zend_weakmap_remove);
117131
static ZEND_FUNCTION(zend_weakmap_dump);
118132
static ZEND_FUNCTION(zend_get_unit_enum);
133+
static ZEND_FUNCTION(zend_test_parameter_with_attribute);
119134
static ZEND_FUNCTION(namespaced_func);
120135
static ZEND_METHOD(_ZendTestClass, is_object);
121136
static ZEND_METHOD(_ZendTestClass, __toString);
122137
static ZEND_METHOD(_ZendTestClass, returnsStatic);
123138
static ZEND_METHOD(_ZendTestClass, returnsThrowable);
124139
static ZEND_METHOD(_ZendTestChildClass, returnsThrowable);
125140
static ZEND_METHOD(_ZendTestTrait, testMethod);
141+
static ZEND_METHOD(ZendTestParameterAttribute, __construct);
142+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, no_override);
143+
static ZEND_METHOD(ZendTestClassWithMethodWithParameterAttribute, override);
144+
static ZEND_METHOD(ZendTestChildClassWithMethodWithParameterAttribute, override);
126145
static ZEND_METHOD(ZendTestNS_Foo, method);
127146
static ZEND_METHOD(ZendTestNS2_Foo, method);
128147
static ZEND_METHOD(ZendTestNS2_ZendSubNS_Foo, method);
@@ -147,6 +166,7 @@ static const zend_function_entry ext_functions[] = {
147166
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
148167
ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump)
149168
ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum)
169+
ZEND_FE(zend_test_parameter_with_attribute, arginfo_zend_test_parameter_with_attribute)
150170
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
151171
ZEND_FE_END
152172
};
@@ -183,6 +203,25 @@ static const zend_function_entry class_ZendTestAttribute_methods[] = {
183203
};
184204

185205

206+
static const zend_function_entry class_ZendTestParameterAttribute_methods[] = {
207+
ZEND_ME(ZendTestParameterAttribute, __construct, arginfo_class_ZendTestParameterAttribute___construct, ZEND_ACC_PUBLIC)
208+
ZEND_FE_END
209+
};
210+
211+
212+
static const zend_function_entry class_ZendTestClassWithMethodWithParameterAttribute_methods[] = {
213+
ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, no_override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_no_override, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
214+
ZEND_ME(ZendTestClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC)
215+
ZEND_FE_END
216+
};
217+
218+
219+
static const zend_function_entry class_ZendTestChildClassWithMethodWithParameterAttribute_methods[] = {
220+
ZEND_ME(ZendTestChildClassWithMethodWithParameterAttribute, override, arginfo_class_ZendTestChildClassWithMethodWithParameterAttribute_override, ZEND_ACC_PUBLIC)
221+
ZEND_FE_END
222+
};
223+
224+
186225
static const zend_function_entry class_ZendTestUnitEnum_methods[] = {
187226
ZEND_FE_END
188227
};
@@ -314,6 +353,43 @@ static zend_class_entry *register_class_ZendTestAttribute(void)
314353
return class_entry;
315354
}
316355

356+
static zend_class_entry *register_class_ZendTestParameterAttribute(void)
357+
{
358+
zend_class_entry ce, *class_entry;
359+
360+
INIT_CLASS_ENTRY(ce, "ZendTestParameterAttribute", class_ZendTestParameterAttribute_methods);
361+
class_entry = zend_register_internal_class_ex(&ce, NULL);
362+
class_entry->ce_flags |= ZEND_ACC_FINAL;
363+
364+
zval property_parameter_default_value;
365+
ZVAL_UNDEF(&property_parameter_default_value);
366+
zend_string *property_parameter_name = zend_string_init("parameter", sizeof("parameter") - 1, 1);
367+
zend_declare_typed_property(class_entry, property_parameter_name, &property_parameter_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING));
368+
zend_string_release(property_parameter_name);
369+
370+
return class_entry;
371+
}
372+
373+
static zend_class_entry *register_class_ZendTestClassWithMethodWithParameterAttribute(void)
374+
{
375+
zend_class_entry ce, *class_entry;
376+
377+
INIT_CLASS_ENTRY(ce, "ZendTestClassWithMethodWithParameterAttribute", class_ZendTestClassWithMethodWithParameterAttribute_methods);
378+
class_entry = zend_register_internal_class_ex(&ce, NULL);
379+
380+
return class_entry;
381+
}
382+
383+
static zend_class_entry *register_class_ZendTestChildClassWithMethodWithParameterAttribute(zend_class_entry *class_entry_ZendTestClassWithMethodWithParameterAttribute)
384+
{
385+
zend_class_entry ce, *class_entry;
386+
387+
INIT_CLASS_ENTRY(ce, "ZendTestChildClassWithMethodWithParameterAttribute", class_ZendTestChildClassWithMethodWithParameterAttribute_methods);
388+
class_entry = zend_register_internal_class_ex(&ce, class_entry_ZendTestClassWithMethodWithParameterAttribute);
389+
390+
return class_entry;
391+
}
392+
317393
static zend_class_entry *register_class_ZendTestUnitEnum(void)
318394
{
319395
zend_class_entry *class_entry = zend_register_internal_enum("ZendTestUnitEnum", IS_UNDEF, class_ZendTestUnitEnum_methods);

0 commit comments

Comments
 (0)