@@ -3445,24 +3445,26 @@ static void reflection_method_invoke(INTERNAL_FUNCTION_PARAMETERS, int variadic)
34453445 }
34463446
34473447 /* For Closure::__invoke(), closures from different source locations have
3448- * different signatures, so we must reject those. However, closures created
3449- * from the same source (e.g. in a loop) share the same op_array and should
3450- * be allowed. For user closures compare op_array.opcodes, for internal
3451- * closures (e.g. var_dump(...)) compare function_name and scope since
3452- * zend_get_closure_method_def() returns a per-object embedded copy. */
3448+ * different signatures, so we must reject those. */
34533449 if (obj_ce == zend_ce_closure && !Z_ISUNDEF (intern -> obj )
34543450 && Z_OBJ_P (object ) != Z_OBJ (intern -> obj )) {
34553451 const zend_function * orig_func = zend_get_closure_method_def (Z_OBJ (intern -> obj ));
34563452 const zend_function * given_func = zend_get_closure_method_def (Z_OBJ_P (object ));
3457- bool same_closure ;
3458- if (orig_func -> type == ZEND_USER_FUNCTION && given_func -> type == ZEND_USER_FUNCTION ) {
3459- same_closure = orig_func -> op_array .opcodes == given_func -> op_array .opcodes ;
3460- } else if (orig_func -> type == ZEND_INTERNAL_FUNCTION && given_func -> type == ZEND_INTERNAL_FUNCTION ) {
3461- same_closure = orig_func -> common .function_name == given_func -> common .function_name
3462- && orig_func -> common .scope == given_func -> common .scope ;
3463- } else {
3464- same_closure = false;
3453+
3454+ bool same_closure = false;
3455+ /* Check if they are either both fake closures or they both are not. */
3456+ if ((orig_func -> common .fn_flags & ZEND_ACC_FAKE_CLOSURE ) == (given_func -> common .fn_flags & ZEND_ACC_FAKE_CLOSURE )) {
3457+ if (orig_func -> common .fn_flags & ZEND_ACC_FAKE_CLOSURE ) {
3458+ /* For fake closures, scope and name must match. */
3459+ same_closure = orig_func -> common .scope == given_func -> common .scope
3460+ && orig_func -> common .function_name == given_func -> common .function_name ;
3461+ } else {
3462+ /* Otherwise the opcode structure must be identical. */
3463+ ZEND_ASSERT (orig_func -> type == ZEND_USER_FUNCTION );
3464+ same_closure = orig_func -> op_array .opcodes == given_func -> op_array .opcodes ;
3465+ }
34653466 }
3467+
34663468 if (!same_closure ) {
34673469 if (!variadic ) {
34683470 efree (params );
0 commit comments