Skip to content

Commit 4418d61

Browse files
committed
Avoid reusing zend_function.common.prototype for magic things (use reserved fields instead).
1 parent f87cc89 commit 4418d61

File tree

5 files changed

+7
-25
lines changed

5 files changed

+7
-25
lines changed

Zend/zend_closures.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ {
236236
fci.size = sizeof(zend_fcall_info);
237237
fci.retval = return_value;
238238

239-
fcc.function_handler = (zend_function *) EX(func)->common.arg_info;
239+
fcc.function_handler = (zend_function *) EX(func)->internal_function.reserved[0];
240240
fci.params = params;
241241
fci.param_count = 2;
242242
ZVAL_STR(&fci.params[0], EX(func)->common.function_name);
@@ -274,7 +274,7 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable,
274274
call.type = ZEND_INTERNAL_FUNCTION;
275275
call.handler = zend_closure_call_magic;
276276
call.function_name = mptr->common.function_name;
277-
call.arg_info = (zend_internal_arg_info *) mptr->common.prototype;
277+
call.reserved[0] = mptr->op_array.reserved[0];
278278
call.scope = mptr->common.scope;
279279

280280
zend_free_trampoline(mptr);

Zend/zend_object_handlers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend
11321132
}
11331133
func->opcodes = &EG(call_trampoline_op);
11341134

1135-
func->prototype = fbc;
1135+
func->reserved[0] = fbc;
11361136
func->scope = fbc->common.scope;
11371137
/* reserve space for arguments, local and temorary variables */
11381138
func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2;

Zend/zend_vm_def.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7669,9 +7669,8 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
76697669
call = execute_data;
76707670
execute_data = EG(current_execute_data) = EX(prev_execute_data);
76717671

7672-
ZEND_ASSERT(zend_vm_calc_used_stack(2, fbc->common.prototype) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
7673-
7674-
call->func = fbc->common.prototype;
7672+
call->func = fbc->op_array.reserved[0];
7673+
ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
76757674
ZEND_CALL_NUM_ARGS(call) = 2;
76767675

76777676
ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);

Zend/zend_vm_execute.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,9 +1955,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
19551955
call = execute_data;
19561956
execute_data = EG(current_execute_data) = EX(prev_execute_data);
19571957

1958-
ZEND_ASSERT(zend_vm_calc_used_stack(2, fbc->common.prototype) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
1959-
1960-
call->func = fbc->common.prototype;
1958+
call->func = fbc->op_array.reserved[0];
1959+
ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
19611960
ZEND_CALL_NUM_ARGS(call) = 2;
19621961

19631962
ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);

ext/reflection/php_reflection.c

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,6 @@ static zend_function *_copy_function(zend_function *fptr) /* {{{ */
195195
}
196196
/* }}} */
197197

198-
static void _fix_closure_prototype(zend_function *fptr) /* {{{ */
199-
{
200-
/* Actually we are setting proxy function's prototype to null
201-
* as for it, the prototype is an object not a function
202-
* which could cause serious problems, see #74949 */
203-
fptr->common.prototype = NULL;
204-
}
205-
/* }}} */
206-
207198
static void _free_function(zend_function *fptr) /* {{{ */
208199
{
209200
if (fptr
@@ -502,7 +493,6 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
502493
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
503494
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
504495
{
505-
_fix_closure_prototype(closure);
506496
mptr = closure;
507497
} else {
508498
closure = NULL;
@@ -2347,7 +2337,6 @@ ZEND_METHOD(reflection_parameter, __construct)
23472337
{
23482338
/* nothing to do. don't set is_closure since is the invoke handler,
23492339
not the closure itself */
2350-
_fix_closure_prototype(fptr);
23512340
} else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
23522341
efree(lcname);
23532342
zend_throw_exception_ex(reflection_exception_ptr, 0,
@@ -3031,7 +3020,6 @@ ZEND_METHOD(reflection_method, __construct)
30313020
&& (mptr = zend_get_closure_invoke_method(Z_OBJ_P(orig_obj))) != NULL)
30323021
{
30333022
/* do nothing, mptr already set */
3034-
_fix_closure_prototype(mptr);
30353023
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, name_len)) == NULL) {
30363024
efree(lcname);
30373025
zend_throw_exception_ex(reflection_exception_ptr, 0,
@@ -4154,15 +4142,13 @@ ZEND_METHOD(reflection_class, getMethod)
41544142
{
41554143
/* don't assign closure_object since we only reflect the invoke handler
41564144
method and not the closure definition itself */
4157-
_fix_closure_prototype(mptr);
41584145
reflection_method_factory(ce, mptr, NULL, return_value);
41594146
efree(lc_name);
41604147
} else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
41614148
&& memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
41624149
&& object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
41634150
/* don't assign closure_object since we only reflect the invoke handler
41644151
method and not the closure definition itself */
4165-
_fix_closure_prototype(mptr);
41664152
reflection_method_factory(ce, mptr, NULL, return_value);
41674153
zval_dtor(&obj_tmp);
41684154
efree(lc_name);
@@ -4189,7 +4175,6 @@ static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval,
41894175
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
41904176
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
41914177
{
4192-
_fix_closure_prototype(closure);
41934178
mptr = closure;
41944179
}
41954180
/* don't assign closure_object since we only reflect the invoke handler
@@ -4241,7 +4226,6 @@ ZEND_METHOD(reflection_class, getMethods)
42414226
if (Z_TYPE(intern->obj) != IS_UNDEF && instanceof_function(ce, zend_ce_closure)) {
42424227
zend_function *closure = zend_get_closure_invoke_method(Z_OBJ(intern->obj));
42434228
if (closure) {
4244-
_fix_closure_prototype(closure);
42454229
_addmethod(closure, ce, return_value, filter, &intern->obj);
42464230
_free_function(closure);
42474231
}

0 commit comments

Comments
 (0)