Skip to content

Commit 9c754da

Browse files
committed
Fix RETURN & SWITCH memory leak issue
1 parent 1b6fae1 commit 9c754da

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

Zend/zend_compile.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,29 @@ void do_pass_param(znode *param, int op, int offset CLS_DC)
832832
}
833833

834834

835-
void do_return(znode *expr CLS_DC)
835+
static void generate_free_switch_expr(zend_switch_entry *switch_entry CLS_DC)
836836
{
837837
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
838838

839+
return;
840+
opline->opcode = ZEND_SWITCH_FREE;
841+
opline->op1 = switch_entry->cond;
842+
SET_UNUSED(opline->op2);
843+
}
844+
845+
846+
void do_return(znode *expr CLS_DC)
847+
{
848+
zend_op *opline;
849+
850+
#ifdef ZTS
851+
zend_stack_apply_with_argument(&CG(switch_cond_stack), (void (*)(void *element, void *)) generate_free_switch_expr, ZEND_STACK_APPLY_TOPDOWN CLS_CC);
852+
#else
853+
zend_stack_apply(&CG(switch_cond_stack), (void (*)(void *element)) generate_free_switch_expr, ZEND_STACK_APPLY_TOPDOWN);
854+
#endif
855+
856+
opline = get_next_op(CG(active_op_array) CLS_CC);
857+
839858
opline->opcode = ZEND_RETURN;
840859
if (expr) {
841860
opline->op1 = *expr;

Zend/zend_stack.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,41 @@ ZEND_API int zend_stack_count(zend_stack *stack)
116116
{
117117
return stack->top;
118118
}
119+
120+
121+
ZEND_API void zend_stack_apply(zend_stack *stack, void (*apply_function)(void *element), int type)
122+
{
123+
int i;
124+
125+
switch (type) {
126+
case ZEND_STACK_APPLY_TOPDOWN:
127+
for (i=stack->top-1; i>=0; i--) {
128+
apply_function(stack->elements[i]);
129+
}
130+
break;
131+
case ZEND_STACK_APPLY_BOTTOMUP:
132+
for (i=0; i<stack->top; i++) {
133+
apply_function(stack->elements[i]);
134+
}
135+
break;
136+
}
137+
}
138+
139+
140+
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, void (*apply_function)(void *element, void *arg), int type, void *arg)
141+
{
142+
int i;
143+
144+
switch (type) {
145+
case ZEND_STACK_APPLY_TOPDOWN:
146+
for (i=stack->top-1; i>=0; i--) {
147+
apply_function(stack->elements[i], arg);
148+
}
149+
break;
150+
case ZEND_STACK_APPLY_BOTTOMUP:
151+
for (i=0; i<stack->top; i++) {
152+
apply_function(stack->elements[i], arg);
153+
}
154+
break;
155+
}
156+
}

Zend/zend_stack.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ ZEND_API int zend_stack_is_empty(zend_stack *stack);
3838
ZEND_API int zend_stack_destroy(zend_stack *stack);
3939
ZEND_API void **zend_stack_base(zend_stack *stack);
4040
ZEND_API int zend_stack_count(zend_stack *stack);
41+
ZEND_API void zend_stack_apply(zend_stack *stack, void (*apply_function)(void *element), int type);
42+
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, void (*apply_function)(void *element, void *arg), int type, void *arg);
4143

44+
#define ZEND_STACK_APPLY_TOPDOWN 1
45+
#define ZEND_STACK_APPLY_BOTTOMUP 2
4246

4347
#endif /* _ZEND_STACK_H */

0 commit comments

Comments
 (0)