File tree Expand file tree Collapse file tree 3 files changed +69
-1
lines changed
tests/closures/closure_const_expr Expand file tree Collapse file tree 3 files changed +69
-1
lines changed Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ #[Attr(static function () { })]
4
+ #[Attr(static function (...$ args ) {
5
+ var_dump ($ args );
6
+ })]
7
+ class C {}
8
+
9
+ ?>
Original file line number Diff line number Diff line change
1
+ --TEST--
2
+ GH-17851: Use-after-free when instantiating autoloaded class with attribute having a Closure parameter.
3
+ --EXTENSIONS--
4
+ reflection
5
+ --FILE--
6
+ <?php
7
+
8
+ spl_autoload_register (static function ($ className ) {
9
+ if ($ className === 'C ' ) {
10
+ require (__DIR__ . '/attributes_autoload.inc ' );
11
+ }
12
+ });
13
+
14
+ #[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE )]
15
+ class Attr {
16
+ public function __construct (public Closure $ value ) {
17
+ $ value ('foo ' );
18
+ }
19
+ }
20
+
21
+ foreach ((new ReflectionClass (C::class))->getAttributes () as $ reflectionAttribute ) {
22
+ var_dump ($ reflectionAttribute ->newInstance ());
23
+ }
24
+
25
+ ?>
26
+ --EXPECTF--
27
+ object(Attr)#%d (1) {
28
+ ["value"]=>
29
+ object(Closure)#%d (3) {
30
+ ["name"]=>
31
+ string(%d) "{closure:%s:%d}"
32
+ ["file"]=>
33
+ string(%d) "%s"
34
+ ["line"]=>
35
+ int(%d)
36
+ }
37
+ }
38
+ array(1) {
39
+ [0]=>
40
+ string(3) "foo"
41
+ }
42
+ object(Attr)#%d (1) {
43
+ ["value"]=>
44
+ object(Closure)#%d (4) {
45
+ ["name"]=>
46
+ string(%d) "{closure:%s:%d}"
47
+ ["file"]=>
48
+ string(%d) "%s"
49
+ ["line"]=>
50
+ int(%d)
51
+ ["parameter"]=>
52
+ array(1) {
53
+ ["$args"]=>
54
+ string(10) "<optional>"
55
+ }
56
+ }
57
+ }
Original file line number Diff line number Diff line change @@ -108,6 +108,7 @@ ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_op_array(zend_op_array *op_arr
108
108
ast -> attr = 0 ;
109
109
ast -> lineno = CG (zend_lineno );
110
110
ast -> op_array = op_array ;
111
+ function_add_ref ((zend_function * )op_array );
111
112
112
113
return (zend_ast * ) ast ;
113
114
}
@@ -1226,7 +1227,8 @@ ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
1226
1227
} else if (EXPECTED (ast -> kind == ZEND_AST_CONSTANT )) {
1227
1228
zend_string_release_ex (zend_ast_get_constant_name (ast ), 0 );
1228
1229
} else if (EXPECTED (ast -> kind == ZEND_AST_OP_ARRAY )) {
1229
- /* Nothing to do. */
1230
+ zend_ast_op_array * op_array = zend_ast_get_op_array (ast );
1231
+ destroy_op_array (op_array -> op_array );
1230
1232
} else if (EXPECTED (zend_ast_is_decl (ast ))) {
1231
1233
zend_ast_decl * decl = (zend_ast_decl * ) ast ;
1232
1234
You can’t perform that action at this time.
0 commit comments