Skip to content

Commit db7193f

Browse files
committed
Fixed bug #79094 (Crashing when running recursion function)
1 parent f0f5c41 commit db7193f

File tree

3 files changed

+39
-6
lines changed

3 files changed

+39
-6
lines changed

Zend/zend_execute.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4452,6 +4452,39 @@ static zend_never_inline int ZEND_FASTCALL zend_quick_check_constant(
44524452
return _zend_quick_get_constant(key, 0, 1 OPLINE_CC EXECUTE_DATA_CC);
44534453
} /* }}} */
44544454

4455+
#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID))
4456+
/* Special versions of functions that sets EX(opline) before calling zend_vm_stack_extend() */
4457+
static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) /* {{{ */
4458+
{
4459+
zend_execute_data *call = (zend_execute_data*)EG(vm_stack_top);
4460+
4461+
ZEND_ASSERT_VM_STACK_GLOBAL;
4462+
4463+
if (UNEXPECTED(used_stack > (size_t)(((char*)EG(vm_stack_end)) - (char*)call))) {
4464+
EX(opline) = opline; /* this is the only difference */
4465+
call = (zend_execute_data*)zend_vm_stack_extend(used_stack);
4466+
ZEND_ASSERT_VM_STACK_GLOBAL;
4467+
zend_vm_init_call_frame(call, call_info | ZEND_CALL_ALLOCATED, func, num_args, object_or_called_scope);
4468+
return call;
4469+
} else {
4470+
EG(vm_stack_top) = (zval*)((char*)call + used_stack);
4471+
zend_vm_init_call_frame(call, call_info, func, num_args, object_or_called_scope);
4472+
return call;
4473+
}
4474+
} /* }}} */
4475+
4476+
static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) /* {{{ */
4477+
{
4478+
uint32_t used_stack = zend_vm_calc_used_stack(num_args, func);
4479+
4480+
return _zend_vm_stack_push_call_frame_ex(used_stack, call_info,
4481+
func, num_args, object_or_called_scope);
4482+
} /* }}} */
4483+
#else
4484+
# define _zend_vm_stack_push_call_frame_ex zend_vm_stack_push_call_frame_ex
4485+
# define _zend_vm_stack_push_call_frame zend_vm_stack_push_call_frame
4486+
#endif
4487+
44554488
#ifdef ZEND_VM_TRACE_HANDLERS
44564489
# include "zend_vm_trace_handlers.h"
44574490
#elif defined(ZEND_VM_TRACE_MAP)

Zend/zend_vm_def.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3783,7 +3783,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
37833783
}
37843784
CACHE_PTR(opline->result.num, fbc);
37853785
}
3786-
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3786+
call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
37873787
fbc, opline->extended_value, NULL);
37883788
call->prev_execute_data = EX(call);
37893789
EX(call) = call;
@@ -3946,7 +3946,7 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
39463946
CACHE_PTR(opline->result.num, fbc);
39473947
}
39483948

3949-
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
3949+
call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
39503950
fbc, opline->extended_value, NULL);
39513951
call->prev_execute_data = EX(call);
39523952
EX(call) = call;
@@ -3976,7 +3976,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT)
39763976
CACHE_PTR(opline->result.num, fbc);
39773977
}
39783978

3979-
call = zend_vm_stack_push_call_frame_ex(
3979+
call = _zend_vm_stack_push_call_frame_ex(
39803980
opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
39813981
fbc, opline->extended_value, NULL);
39823982
call->prev_execute_data = EX(call);

Zend/zend_vm_execute.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2897,7 +2897,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME
28972897
}
28982898
CACHE_PTR(opline->result.num, fbc);
28992899
}
2900-
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
2900+
call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
29012901
fbc, opline->extended_value, NULL);
29022902
call->prev_execute_data = EX(call);
29032903
EX(call) = call;
@@ -2984,7 +2984,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
29842984
CACHE_PTR(opline->result.num, fbc);
29852985
}
29862986

2987-
call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
2987+
call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
29882988
fbc, opline->extended_value, NULL);
29892989
call->prev_execute_data = EX(call);
29902990
EX(call) = call;
@@ -3014,7 +3014,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO
30143014
CACHE_PTR(opline->result.num, fbc);
30153015
}
30163016

3017-
call = zend_vm_stack_push_call_frame_ex(
3017+
call = _zend_vm_stack_push_call_frame_ex(
30183018
opline->op1.num, ZEND_CALL_NESTED_FUNCTION,
30193019
fbc, opline->extended_value, NULL);
30203020
call->prev_execute_data = EX(call);

0 commit comments

Comments
 (0)