From 69625406620c5dd565b3cdd1cdafb30d32029428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 17 Mar 2025 13:55:24 +0100 Subject: [PATCH] =?UTF-8?q?zend=5Fget=5Fcallable=5Fname:=20Return=20underl?= =?UTF-8?q?ying=20callable=E2=80=99s=20name=20for=20fake=20closures=20(#18?= =?UTF-8?q?063)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes php/php-src#18062 --- NEWS | 2 ++ UPGRADING.INTERNALS | 2 ++ Zend/tests/first_class_callable/gh18062.phpt | 32 ++++++++++++++++++++ Zend/zend_API.c | 13 ++++++++ 4 files changed, 49 insertions(+) create mode 100644 Zend/tests/first_class_callable/gh18062.phpt diff --git a/NEWS b/NEWS index e498fac1d82..48e71a0a806 100644 --- a/NEWS +++ b/NEWS @@ -169,6 +169,8 @@ PHP NEWS - Standard: . Fixed crypt() tests on musl when using --with-external-libcrypt (Michael Orlitzky). + . Fixed bug GH-18062 (is_callable(func(...), callable_name: $name) for first + class callables returns wrong name). (timwolla) - Streams: . Fixed bug GH-16889 (stream_select() timeout useless for pipes on Windows). diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index b963ead5cc8..d2ab4e13fc5 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -19,6 +19,8 @@ PHP 8.5 INTERNALS UPGRADE NOTES a value to a non-reference zval. . Added zval_ptr_safe_dtor() to safely destroy a zval when a destructor could interfere. + . zend_get_callable_name() now returns the name of the underlying function + for fake closures. ======================== 2. Build system changes diff --git a/Zend/tests/first_class_callable/gh18062.phpt b/Zend/tests/first_class_callable/gh18062.phpt new file mode 100644 index 00000000000..3865dd77adb --- /dev/null +++ b/Zend/tests/first_class_callable/gh18062.phpt @@ -0,0 +1,32 @@ +--TEST-- +First Class Callable returns correct name from is_callable() +--FILE-- + +--EXPECT-- +string(9) "some_func" +string(13) "Foo::__invoke" +string(8) "Foo::bar" diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 162f9aced14..2be3d428270 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -4134,6 +4134,19 @@ try_again: case IS_OBJECT: { zend_class_entry *ce = Z_OBJCE_P(callable); + + if (ce == zend_ce_closure) { + const zend_function *fn = zend_get_closure_method_def(Z_OBJ_P(callable)); + + if (fn->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + if (fn->common.scope) { + return zend_create_member_string(fn->common.scope->name, fn->common.function_name); + } else { + return zend_string_copy(fn->common.function_name); + } + } + } + return zend_string_concat2( ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), "::__invoke", sizeof("::__invoke") - 1);