Skip to content

Commit ae16471

Browse files
nielsdosfabio-ivona
authored andcommitted
Fix phpGH-10623: ReflectionFunction::getClosureUsedVariables() returns empty array in presence of variadic arguments
The code was missing the handling for the RECV_VARIADIC instruction. Additional regression test for phpGH-10623 Co-authored-by: Fabio Ivona <[email protected]>
1 parent a9e4f51 commit ae16471

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ PHP NEWS
4545
- Phar:
4646
. Fix incorrect check in phar tar parsing. (nielsdos)
4747

48+
- Reflection:
49+
. Fixed bug GH-10623 (Reflection::getClosureUsedVariables opcode fix with
50+
variadic arguments). (nielsdos)
51+
4852
- Standard:
4953
. Fixed bug GH-10292 (Made the default value of the first param of srand() and
5054
mt_srand() unknown). (kocsismate)

ext/reflection/php_reflection.c

+4
Original file line numberDiff line numberDiff line change
@@ -1747,6 +1747,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, getClosureUsedVariables)
17471747
}
17481748

17491749
zend_op *opline = ops->opcodes + ops->num_args;
1750+
if (ops->fn_flags & ZEND_ACC_VARIADIC) {
1751+
ZEND_ASSERT(opline->opcode == ZEND_RECV_VARIADIC);
1752+
opline++;
1753+
}
17501754

17511755
for (; opline->opcode == ZEND_BIND_STATIC; opline++) {
17521756
if (!(opline->extended_value & (ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))) {

ext/reflection/tests/gh10623.phpt

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
--TEST--
2+
GH-10623 (ReflectionFunction::getClosureUsedVariables() returns empty array in presence of variadic arguments)
3+
--FILE--
4+
<?php
5+
6+
$data1 = 1;
7+
$data2 = 2;
8+
$data3 = 3;
9+
10+
$closure = function($var) use($data1) {};
11+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
12+
13+
$closure = function($var, ...$variadic) {};
14+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
15+
16+
$closure = function($var, ...$variadic) use($data1) {};
17+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
18+
19+
$closure = function($var, ...$variadic) use($data1, $data2, $data3) {};
20+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
21+
22+
$closure = function(...$variadic) use($data1) {};
23+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
24+
25+
$closure = function($var, $var2, ...$variadic) {};
26+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
27+
28+
$closure = function($var, $var2, $var3, ...$variadic) use($data1, $data2, $data3) {};
29+
var_dump((new ReflectionFunction($closure))->getClosureUsedVariables());
30+
31+
?>
32+
--EXPECT--
33+
array(1) {
34+
["data1"]=>
35+
int(1)
36+
}
37+
array(0) {
38+
}
39+
array(1) {
40+
["data1"]=>
41+
int(1)
42+
}
43+
array(3) {
44+
["data1"]=>
45+
int(1)
46+
["data2"]=>
47+
int(2)
48+
["data3"]=>
49+
int(3)
50+
}
51+
array(1) {
52+
["data1"]=>
53+
int(1)
54+
}
55+
array(0) {
56+
}
57+
array(3) {
58+
["data1"]=>
59+
int(1)
60+
["data2"]=>
61+
int(2)
62+
["data3"]=>
63+
int(3)
64+
}

0 commit comments

Comments
 (0)