Skip to content

Commit 4f1d538

Browse files
committed
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fixed bug #78689
2 parents 2252395 + 33dd25d commit 4f1d538

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

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

288294
if (!mptr->common.scope) {
289295
return FAILURE;
@@ -298,6 +304,7 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
298304
}
299305
}
300306

307+
memset(&call, 0, sizeof(zend_internal_function));
301308
call.type = ZEND_INTERNAL_FUNCTION;
302309
call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC;
303310
call.handler = zend_closure_call_magic;

0 commit comments

Comments
 (0)