Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9e6a5bf

Browse files
Fix caching arg by name
Non-persistent arg infos allocated by pdo_hash_methods() break zend_get_arg_offset_by_name() again. Fix zend_get_arg_offset_by_name() by excluding ZEND_ACC_NEVER_CACHE instead of ZEND_ACC_USER_ARG_INFO. Also flag Closure::__invoke() with ZEND_ACC_NEVER_CACHE (It was already flagged with ZEND_ACC_CALL_VIA_HANDLER, which is synonymous of ZEND_ACC_NEVER_CACHE WRT caching). This would allow to remove ZEND_ACC_USER_ARG_INFO later.
1 parent bb512d0 commit 9e6a5bf

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

‎Zend/tests/closures/gh19653_3.phpt‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-19653 (Closure named argument unpacking between temporary closures can cause a crash) - temporary method variation
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
function usage1($f) {
9+
$f(tmpMethodParamName: null);
10+
}
11+
12+
usage1([new _ZendTestClass(), 'testTmpMethodWithArgInfo']);
13+
usage1(eval('return function (string $a, string $b): string { return $a.$b; };'));
14+
15+
?>
16+
--EXPECTF--
17+
Fatal error: Uncaught Error: Unknown named parameter $tmpMethodParamName in %s:%d
18+
Stack trace:
19+
#0 %s(%d): usage1(Object(Closure))
20+
#1 {main}
21+
thrown in %s on line %d

‎Zend/zend_closures.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* {
497497
* ZEND_ACC_USER_ARG_INFO flag to prevent invalid usage by Reflection */
498498
invoke->type = ZEND_INTERNAL_FUNCTION;
499499
invoke->internal_function.fn_flags =
500-
ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & keep_flags);
500+
ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE | (closure->func.common.fn_flags & keep_flags);
501501
if (closure->func.type != ZEND_INTERNAL_FUNCTION || (closure->func.common.fn_flags & ZEND_ACC_USER_ARG_INFO)) {
502502
invoke->internal_function.fn_flags |=
503503
ZEND_ACC_USER_ARG_INFO;

‎Zend/zend_execute.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5478,7 +5478,7 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name(
54785478
if ((fbc->type == ZEND_USER_FUNCTION
54795479
&& (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE)))
54805480
|| (fbc->type == ZEND_INTERNAL_FUNCTION
5481-
&& !(fbc->common.fn_flags & ZEND_ACC_USER_ARG_INFO))) {
5481+
&& !(fbc->common.fn_flags & ZEND_ACC_NEVER_CACHE))) {
54825482
*cache_slot = unique_id;
54835483
*(uintptr_t *)(cache_slot + 1) = i;
54845484
}
@@ -5490,7 +5490,7 @@ static zend_always_inline uint32_t zend_get_arg_offset_by_name(
54905490
if ((fbc->type == ZEND_USER_FUNCTION
54915491
&& (!fbc->op_array.refcount || !(fbc->op_array.fn_flags & ZEND_ACC_CLOSURE)))
54925492
|| (fbc->type == ZEND_INTERNAL_FUNCTION
5493-
&& !(fbc->common.fn_flags & ZEND_ACC_USER_ARG_INFO))) {
5493+
&& !(fbc->common.fn_flags & ZEND_ACC_NEVER_CACHE))) {
54945494
*cache_slot = unique_id;
54955495
*(uintptr_t *)(cache_slot + 1) = fbc->common.num_args;
54965496
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /