Skip to content

Commit 2e999ba

Browse files
authored
Fix ReflectionFunction::isDeprecated() for materialized __call() (#17914)
* Fix `ReflectionFunction::isDeprecated()` for materialized `__call()` Fixes #17913 * NEWS
1 parent 8be263d commit 2e999ba

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PHP NEWS
99
(ilutov)
1010
. Fixed bug GH-17376 (Broken JIT polymorphism for property hooks added to
1111
child class). (ilutov)
12+
. Fixed bug GH-17913 (ReflectionFunction::isDeprecated() returns incorrect
13+
results for closures created from magic __call()). (timwolla)
1214

1315
27 Feb 2025, PHP 8.4.5
1416

Zend/zend_closures.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,12 @@ static zend_result zend_create_closure_from_callable(zval *return_value, zval *c
361361

362362
memset(&call, 0, sizeof(zend_internal_function));
363363
call.type = ZEND_INTERNAL_FUNCTION;
364-
call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC;
364+
call.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_DEPRECATED);
365365
call.handler = zend_closure_call_magic;
366366
call.function_name = mptr->common.function_name;
367367
call.scope = mptr->common.scope;
368368
call.doc_comment = NULL;
369+
call.attributes = mptr->common.attributes;
369370

370371
zend_free_trampoline(mptr);
371372
mptr = (zend_function *) &call;
@@ -871,14 +872,15 @@ void zend_closure_from_frame(zval *return_value, zend_execute_data *call) { /* {
871872

872873
memset(&trampoline, 0, sizeof(zend_internal_function));
873874
trampoline.type = ZEND_INTERNAL_FUNCTION;
874-
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE);
875+
trampoline.fn_flags = mptr->common.fn_flags & (ZEND_ACC_STATIC | ZEND_ACC_VARIADIC | ZEND_ACC_RETURN_REFERENCE | ZEND_ACC_DEPRECATED);
875876
trampoline.handler = zend_closure_call_magic;
876877
trampoline.function_name = mptr->common.function_name;
877878
trampoline.scope = mptr->common.scope;
878879
trampoline.doc_comment = NULL;
879880
if (trampoline.fn_flags & ZEND_ACC_VARIADIC) {
880881
trampoline.arg_info = trampoline_arg_info;
881882
}
883+
trampoline.attributes = mptr->common.attributes;
882884

883885
zend_free_trampoline(mptr);
884886
mptr = (zend_function *) &trampoline;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--TEST--
2+
GH-17913: ReflectionClassConstant::isDeprecated() with __call() and __callStatic()
3+
--FILE--
4+
<?php
5+
6+
class Clazz {
7+
#[\Deprecated]
8+
function __call(string $name, array $params) {
9+
}
10+
11+
#[\Deprecated("due to some reason")]
12+
static function __callStatic(string $name, array $params) {
13+
}
14+
}
15+
16+
$foo = new Clazz;
17+
$closure = Closure::fromCallable([$foo, 'test']);
18+
19+
$rc = new ReflectionFunction($closure);
20+
var_dump($rc->getAttributes()[0]->newInstance());
21+
var_dump($rc->isDeprecated());
22+
23+
$closure = $foo->test(...);
24+
25+
$rc = new ReflectionFunction($closure);
26+
var_dump($rc->getAttributes()[0]->newInstance());
27+
var_dump($rc->isDeprecated());
28+
29+
$closure = Closure::fromCallable('Clazz::test');
30+
31+
$rc = new ReflectionFunction($closure);
32+
var_dump($rc->getAttributes()[0]->newInstance());
33+
var_dump($rc->isDeprecated());
34+
35+
$closure = Clazz::test(...);
36+
37+
$rc = new ReflectionFunction($closure);
38+
var_dump($rc->getAttributes()[0]->newInstance());
39+
var_dump($rc->isDeprecated());
40+
41+
?>
42+
--EXPECTF--
43+
object(Deprecated)#%d (2) {
44+
["message"]=>
45+
NULL
46+
["since"]=>
47+
NULL
48+
}
49+
bool(true)
50+
object(Deprecated)#%d (2) {
51+
["message"]=>
52+
NULL
53+
["since"]=>
54+
NULL
55+
}
56+
bool(true)
57+
object(Deprecated)#%d (2) {
58+
["message"]=>
59+
string(18) "due to some reason"
60+
["since"]=>
61+
NULL
62+
}
63+
bool(true)
64+
object(Deprecated)#%d (2) {
65+
["message"]=>
66+
string(18) "due to some reason"
67+
["since"]=>
68+
NULL
69+
}
70+
bool(true)

0 commit comments

Comments
 (0)