Skip to content

Commit 565a416

Browse files
committed
Fix attribute target validation on fake closures
Fixes GH-8982 Closes GH-9173
1 parent dd241c0 commit 565a416

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ PHP NEWS
7272
- Reflection:
7373
. Fixed bug GH-8943 (Fixed Reflection::getModifiersNames() with readonly
7474
modifier). (Pierrick)
75+
. Fixed bug GH-8982 (Attribute with TARGET_METHOD is rejected on fake
76+
closure of method). (ilutov)
7577

7678
- Standard:
7779
. Fixed the crypt_sha256/512 api build with clang > 12. (David Carlier)

ext/reflection/php_reflection.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes)
18821882

18831883
GET_REFLECTION_OBJECT_PTR(fptr);
18841884

1885-
if (fptr->common.scope && !(fptr->common.fn_flags & ZEND_ACC_CLOSURE)) {
1885+
if (fptr->common.scope && (fptr->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) {
18861886
target = ZEND_ATTRIBUTE_TARGET_METHOD;
18871887
} else {
18881888
target = ZEND_ATTRIBUTE_TARGET_FUNCTION;

ext/reflection/tests/gh8982.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
GH-8982 (Attribute target validation fails when read via ReflectionFunction)
3+
--FILE--
4+
<?php
5+
6+
#[Attribute(Attribute::TARGET_FUNCTION)]
7+
class F
8+
{
9+
}
10+
11+
#[Attribute(Attribute::TARGET_METHOD)]
12+
class M
13+
{
14+
}
15+
16+
class C
17+
{
18+
#[F]
19+
#[M]
20+
public function m()
21+
{
22+
}
23+
}
24+
25+
#[F]
26+
#[M]
27+
function f() {}
28+
29+
function test(string $attributeClass, $value) {
30+
try {
31+
var_dump((new ReflectionFunction($value))->getAttributes($attributeClass)[0]->newInstance());
32+
} catch (Error $e) {
33+
echo $e->getMessage(), "\n";
34+
}
35+
}
36+
37+
$m = [new C(), 'm'](...);
38+
$f = f(...);
39+
40+
test(F::class, $f);
41+
test(M::class, $f);
42+
test(F::class, $m);
43+
test(M::class, $m);
44+
45+
?>
46+
--EXPECT--
47+
object(F)#4 (0) {
48+
}
49+
Attribute "M" cannot target function (allowed targets: method)
50+
Attribute "F" cannot target method (allowed targets: function)
51+
object(M)#4 (0) {
52+
}

0 commit comments

Comments
 (0)