Fix ReflectionMethod::invoke() with internal closures#21389
Fix ReflectionMethod::invoke() with internal closures#21389iliaal wants to merge 1 commit intophp:masterfrom
Conversation
The closure identity check added in phpGH-21366 accessed op_array.opcodes unconditionally, but internal closures (e.g. var_dump(...)) use internal_function, not op_array. This caused undefined behavior when comparing closures created via first-class callable syntax on internal functions. Check the function type first: compare op_array.opcodes for user closures, compare the function pointer directly for internal closures.
|
On first sight this seems right. One other thing that I notice is that |
|
I think it should be fine, but another pair of eyes never hurts :-) Thanks! |
I don't think that's possible for the reason you've mentioned. We're keeping the |
| // Internal closures (first-class callable syntax) should also be validated | ||
| $vd = var_dump(...); | ||
| $pr = print_r(...); |
There was a problem hiding this comment.
Can we, for completeness, also add a test for:
- First-class-callables of a userland-defined function.
- Trying to pass a userland Closure to
invoke()created for a internal Closure and vice versa.
Summary
Follow-up to GH-21366. The closure identity check accessed
op_array.opcodesunconditionally, but internal closures created via first-class callable syntax (e.g.var_dump(...)) useinternal_function, notop_array. This is undefined behavior and will crash under ASAN/debug builds.func->type == ZEND_USER_FUNCTIONbefore accessingop_array.opcodeszend_functionpointer directlyReported by @ndossche in #21366 (comment)