diff options
| author | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-29 15:07:28 +0100 |
|---|---|---|
| committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-29 15:07:28 +0100 |
| commit | 4f1d5380e2669b375a89d7b22d8dd3c9a7d3cde1 (patch) | |
| tree | 4bbf29d7cab436a6a7a3f5cc7eaa9547976c80b4 | |
| parent | 22523958f4bf36b396b39e7ae32d20083678cf04 (diff) | |
| parent | 33dd25d21c2dc4306c3b4d7ce50cf9d5186723ef (diff) | |
| download | php-git-4f1d5380e2669b375a89d7b22d8dd3c9a7d3cde1.tar.gz | |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Fixed bug #78689
| -rw-r--r-- | Zend/tests/bug78689.phpt | 13 | ||||
| -rw-r--r-- | Zend/zend_closures.c | 9 |
2 files changed, 21 insertions, 1 deletions
diff --git a/Zend/tests/bug78689.phpt b/Zend/tests/bug78689.phpt new file mode 100644 index 0000000000..2273fd3532 --- /dev/null +++ b/Zend/tests/bug78689.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #78689: Closure::fromCallable() doesn't handle [Closure, '__invoke'] +--FILE-- +<?php +$a = [function () { echo "123\n"; }, '__invoke']; +$a(); + +$b = Closure::fromCallable($a); +$b(); +?> +--EXPECT-- +123 +123 diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index de80902852..6febea86b9 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -283,7 +283,13 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, mptr = fcc.function_handler; if (mptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - memset(&call, 0, sizeof(zend_internal_function)); + /* For Closure::fromCallable([$closure, "__invoke"]) return $closure. */ + if (fcc.object && fcc.object->ce == zend_ce_closure + && zend_string_equals_literal(mptr->common.function_name, "__invoke")) { + ZVAL_OBJ(return_value, fcc.object); + zend_free_trampoline(mptr); + return SUCCESS; + } if (!mptr->common.scope) { return FAILURE; @@ -298,6 +304,7 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, } } + memset(&call, 0, sizeof(zend_internal_function)); call.type = ZEND_INTERNAL_FUNCTION; call.fn_flags = mptr->common.fn_flags & ZEND_ACC_STATIC; call.handler = zend_closure_call_magic; |
