Skip to content

Commit 2152bb2

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix attribute target validation on fake closures
2 parents fdb9e3a + 565a416 commit 2152bb2

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

ext/reflection/php_reflection.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1901,7 +1901,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes)
19011901

19021902
GET_REFLECTION_OBJECT_PTR(fptr);
19031903

1904-
if (fptr->common.scope && !(fptr->common.fn_flags & ZEND_ACC_CLOSURE)) {
1904+
if (fptr->common.scope && (fptr->common.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) {
19051905
target = ZEND_ATTRIBUTE_TARGET_METHOD;
19061906
} else {
19071907
target = ZEND_ATTRIBUTE_TARGET_FUNCTION;

ext/reflection/tests/gh8982.phpt

+52
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)