Skip to content

Commit f9895b4

Browse files
committed
Fixed bug #78689
1 parent 2bdb13a commit f9895b4

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PHP NEWS
77
Lundin)
88
. Fixed bug #78752 (Segfault if GC triggered while generator stack frame is
99
being destroyed). (Nikita)
10+
. Fixed bug #78689 (Closure::fromCallable() doesn't handle
11+
[Closure, '__invoke']). (Nikita)
1012

1113
- COM:
1214
. Fixed bug #78694 (Appending to a variant array causes segfault). (cmb)

Zend/tests/bug78689.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #78689: Closure::fromCallable() doesn't handle [Closure, '__invoke']
3+
--FILE--
4+
<?php
5+
$a = [function () { echo "123\n"; }, '__invoke'];
6+
$a();
7+
8+
$b = Closure::fromCallable($a);
9+
$b();
10+
?>
11+
--EXPECT--
12+
123
13+
123

Zend/zend_closures.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,15 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
268268

269269
mptr = fcc.function_handler;
270270
if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
271-
memset(&call, 0, sizeof(zend_internal_function));
271+
/* For Closure::fromCallable([$closure, "__invoke"]) return $closure. */
272+
if (fcc.object && fcc.object->ce == zend_ce_closure
273+
&& zend_string_equals_literal(mptr->common.function_name, "__invoke")) {
274+
ZVAL_OBJ(return_value, fcc.object);
275+
zend_free_trampoline(mptr);
276+
return SUCCESS;
277+
}
272278

279+
memset(&call, 0, sizeof(zend_internal_function));
273280
call.type = ZEND_INTERNAL_FUNCTION;
274281
call.handler = zend_closure_call_magic;
275282
call.function_name = mptr->common.function_name;

0 commit comments

Comments
 (0)