Skip to content

Commit 4263b3b

Browse files
committed
Fixed attribute class validation bug.
1 parent ea9277b commit 4263b3b

File tree

2 files changed

+29
-10
lines changed

2 files changed

+29
-10
lines changed

Zend/tests/attributes/005_objects.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Attributes can be converted into objects.
33
--FILE--
44
<?php
55

6+
<<PhpAttribute>>
67
class A1
78
{
89
public string $name;
@@ -55,6 +56,7 @@ try {
5556

5657
echo "\n";
5758

59+
<<PhpAttribute>>
5860
class A3
5961
{
6062
private function __construct() { }
@@ -70,6 +72,7 @@ try {
7072

7173
echo "\n";
7274

75+
<<PhpAttribute>>
7376
class A4 { }
7477

7578
$ref = new \ReflectionFunction(<<A4(1)>> function () { });
@@ -80,6 +83,18 @@ try {
8083
var_dump('ERROR 5', $e->getMessage());
8184
}
8285

86+
echo "\n";
87+
88+
class A5 { }
89+
90+
$ref = new \ReflectionFunction(<<A5>> function () { });
91+
92+
try {
93+
$ref->getAttributes()[0]->newInstance();
94+
} catch (\Error $e) {
95+
var_dump('ERROR 6', $e->getMessage());
96+
}
97+
8398
?>
8499
--EXPECT--
85100
string(2) "A1"
@@ -100,3 +115,6 @@ string(50) "Attribute constructor of class 'A3' must be public"
100115

101116
string(7) "ERROR 5"
102117
string(71) "Attribute class 'A4' does not have a constructor, cannot pass arguments"
118+
119+
string(7) "ERROR 6"
120+
string(78) "Attempting to use class 'A5' as attribute that does not have <<PhpAttribute>>."

ext/reflection/php_reflection.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6655,6 +6655,7 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
66556655
attribute_reference *attr;
66566656

66576657
zend_class_entry *ce;
6658+
zend_string *lcname;
66586659
zval obj;
66596660

66606661
zval *args = NULL;
@@ -6672,23 +6673,23 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
66726673
RETURN_THROWS();
66736674
}
66746675

6675-
if (SUCCESS != object_init_ex(&obj, ce)) {
6676-
RETURN_THROWS();
6677-
}
6678-
6679-
zend_string *lower_name = zend_string_tolower_ex(ce->name, 1);
6676+
lcname = zend_string_tolower(ce->name);
66806677

6681-
if (ce->type == ZEND_USER_CLASS && ce->info.user.attributes && zend_hash_str_exists(ce->info.user.attributes, "phpattribute", sizeof("phpattribute")-1) == 0) {
6682-
zend_string_release(lower_name);
6678+
if (ce->type == ZEND_USER_CLASS && (!ce->info.user.attributes || !zend_hash_str_exists(ce->info.user.attributes, ZEND_STRL("phpattribute")))) {
6679+
zend_string_release(lcname);
66836680
zend_throw_error(NULL, "Attempting to use class '%s' as attribute that does not have <<PhpAttribute>>.", ZSTR_VAL(attr->name));
66846681
RETURN_THROWS();
6685-
} else if (ce->type == ZEND_INTERNAL_CLASS && zend_hash_exists(&zend_attributes_internal_validators, lower_name) == 0) {
6686-
zend_string_release(lower_name);
6682+
} else if (ce->type == ZEND_INTERNAL_CLASS && zend_hash_exists(&zend_attributes_internal_validators, lcname) == 0) {
6683+
zend_string_release(lcname);
66876684
zend_throw_error(NULL, "Attempting to use internal class '%s' as attribute that does not have <<PhpCompilerAttribute>>.", ZSTR_VAL(attr->name));
66886685
RETURN_THROWS();
66896686
}
66906687

6691-
zend_string_release(lower_name);
6688+
zend_string_release(lcname);
6689+
6690+
if (SUCCESS != object_init_ex(&obj, ce)) {
6691+
RETURN_THROWS();
6692+
}
66926693

66936694
count = zend_hash_num_elements(Z_ARRVAL(attr->arguments));
66946695

0 commit comments

Comments
 (0)