From 9c754da0fcec0ca1c466618e4605c69d24745350 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Sat, 24 Jul 1999 11:43:21 +0000 Subject: [PATCH] Fix RETURN & SWITCH memory leak issue --- Zend/zend_compile.c | 21 ++++++++++++++++++++- Zend/zend_stack.c | 38 ++++++++++++++++++++++++++++++++++++++ Zend/zend_stack.h | 4 ++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 67fed1297f..634ebb8c3f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -832,10 +832,29 @@ void do_pass_param(znode *param, int op, int offset CLS_DC) } -void do_return(znode *expr CLS_DC) +static void generate_free_switch_expr(zend_switch_entry *switch_entry CLS_DC) { zend_op *opline = get_next_op(CG(active_op_array) CLS_CC); + return; + opline->opcode = ZEND_SWITCH_FREE; + opline->op1 = switch_entry->cond; + SET_UNUSED(opline->op2); +} + + +void do_return(znode *expr CLS_DC) +{ + zend_op *opline; + +#ifdef ZTS + zend_stack_apply_with_argument(&CG(switch_cond_stack), (void (*)(void *element, void *)) generate_free_switch_expr, ZEND_STACK_APPLY_TOPDOWN CLS_CC); +#else + zend_stack_apply(&CG(switch_cond_stack), (void (*)(void *element)) generate_free_switch_expr, ZEND_STACK_APPLY_TOPDOWN); +#endif + + opline = get_next_op(CG(active_op_array) CLS_CC); + opline->opcode = ZEND_RETURN; if (expr) { opline->op1 = *expr; diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c index 1a4b062add..0f3b0f6aac 100644 --- a/Zend/zend_stack.c +++ b/Zend/zend_stack.c @@ -116,3 +116,41 @@ ZEND_API int zend_stack_count(zend_stack *stack) { return stack->top; } + + +ZEND_API void zend_stack_apply(zend_stack *stack, void (*apply_function)(void *element), int type) +{ + int i; + + switch (type) { + case ZEND_STACK_APPLY_TOPDOWN: + for (i=stack->top-1; i>=0; i--) { + apply_function(stack->elements[i]); + } + break; + case ZEND_STACK_APPLY_BOTTOMUP: + for (i=0; itop; i++) { + apply_function(stack->elements[i]); + } + break; + } +} + + +ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, void (*apply_function)(void *element, void *arg), int type, void *arg) +{ + int i; + + switch (type) { + case ZEND_STACK_APPLY_TOPDOWN: + for (i=stack->top-1; i>=0; i--) { + apply_function(stack->elements[i], arg); + } + break; + case ZEND_STACK_APPLY_BOTTOMUP: + for (i=0; itop; i++) { + apply_function(stack->elements[i], arg); + } + break; + } +} diff --git a/Zend/zend_stack.h b/Zend/zend_stack.h index 520f010924..5e084fd74f 100644 --- a/Zend/zend_stack.h +++ b/Zend/zend_stack.h @@ -38,6 +38,10 @@ ZEND_API int zend_stack_is_empty(zend_stack *stack); ZEND_API int zend_stack_destroy(zend_stack *stack); ZEND_API void **zend_stack_base(zend_stack *stack); ZEND_API int zend_stack_count(zend_stack *stack); +ZEND_API void zend_stack_apply(zend_stack *stack, void (*apply_function)(void *element), int type); +ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, void (*apply_function)(void *element, void *arg), int type, void *arg); +#define ZEND_STACK_APPLY_TOPDOWN 1 +#define ZEND_STACK_APPLY_BOTTOMUP 2 #endif /* _ZEND_STACK_H */ -- 2.50.0