Skip to content

Commit 4963701

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fixed bug #78689
2 parents 817fbe8 + 4f1d538 commit 4963701

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

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
@@ -280,7 +280,13 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
280280

281281
mptr = fcc.function_handler;
282282
if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
283-
memset(&call, 0, sizeof(zend_internal_function));
283+
/* For Closure::fromCallable([$closure, "__invoke"]) return $closure. */
284+
if (fcc.object && fcc.object->ce == zend_ce_closure
285+
&& zend_string_equals_literal(mptr->common.function_name, "__invoke")) {
286+
ZVAL_OBJ(return_value, fcc.object);
287+
zend_free_trampoline(mptr);
288+
return SUCCESS;
289+
}
284290

285291
if (!mptr->common.scope) {
286292
return FAILURE;
@@ -295,6 +301,7 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
295301
}
296302
}
297303

304+
memset(&call, 0, sizeof(zend_internal_function));
298305
call.type = ZEND_INTERNAL_FUNCTION;
299306
call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC;
300307
call.handler = zend_closure_call_magic;

0 commit comments

Comments
 (0)