Skip to content

Commit e1e2226

Browse files
author
Andi Gutmans
committed
- Fix various memory leaks.
1 parent d86ed82 commit e1e2226

File tree

4 files changed

+27
-18
lines changed

4 files changed

+27
-18
lines changed

Zend/zend-parser.y

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ encaps_list:
605605

606606
encaps_var:
607607
VARIABLE { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
608-
| VARIABLE '[' encaps_var_offset ']' { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$1, &$3 CLS_CC); }
608+
| VARIABLE '[' { do_begin_variable_parse(CLS_C); } encaps_var_offset ']' { do_fetch_globals(&$1); fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
609609
| VARIABLE ZEND_OBJECT_OPERATOR STRING { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$2, &$1, 1 CLS_CC); do_fetch_property(&$$, &$2, &$3 CLS_CC); }
610610
| DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
611611
| DOLLAR_OPEN_CURLY_BRACES STRING '[' expr ']' '}' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$2, &$4 CLS_CC); }
@@ -616,7 +616,7 @@ encaps_var:
616616
encaps_var_offset:
617617
STRING { $$ = $1; }
618618
| NUM_STRING { $$ = $1; }
619-
| { do_begin_variable_parse(CLS_C); } VARIABLE { fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
619+
| VARIABLE { fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
620620
;
621621

622622

Zend/zend_compile.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,12 +937,17 @@ void do_brk_cont(int op, znode *expr CLS_DC)
937937
void do_switch_cond(znode *cond CLS_DC)
938938
{
939939
zend_switch_entry switch_entry;
940+
zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
940941

941942
switch_entry.cond = *cond;
942943
switch_entry.default_case = -1;
943944
switch_entry.control_var = -1;
944945
zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
945946

947+
if (opline->result.op_type == IS_VAR) {
948+
opline->result.u.EA.type |= EXT_TYPE_UNUSED;
949+
}
950+
946951
do_begin_loop(CLS_C);
947952

948953
INC_BPC(CG(active_op_array));

Zend/zend_execute.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,9 @@ binary_assign_op_addr: {
15521552
}
15531553
break;
15541554
case ZEND_CASE:
1555+
if (opline->op1.op_type == IS_VAR) {
1556+
EG(AiCount)++;
1557+
}
15551558
is_equal_function(&Ts[opline->result.u.var].tmp_var,
15561559
get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R),
15571560
get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R) );

Zend/zend_execute_API.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,6 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n
278278
return FAILURE;
279279
}
280280

281-
function_state.function_symbol_table = (HashTable *) emalloc(sizeof(HashTable));
282-
zend_hash_init(function_state.function_symbol_table, 0, NULL, PVAL_PTR_DTOR, 0);
283281

284282
for (i=0; i<param_count; i++) {
285283
zval *param;
@@ -293,35 +291,38 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n
293291
zend_ptr_stack_push(&EG(argument_stack), param);
294292
}
295293

296-
if (object) {
297-
zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr;
298-
299-
var_uninit(dummy);
300-
dummy->refcount=1;
301-
dummy->is_ref=0;
302-
zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr);
303-
zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC);
304-
}
294+
zend_ptr_stack_push(&EG(argument_stack), (void *) param_count);
305295

306-
calling_symbol_table = EG(active_symbol_table);
307-
EG(active_symbol_table) = function_state.function_symbol_table;
308296
var_uninit(retval);
309297
if (function_state.function->type == ZEND_USER_FUNCTION) {
298+
calling_symbol_table = EG(active_symbol_table);
299+
EG(active_symbol_table) = (HashTable *) emalloc(sizeof(HashTable));
300+
zend_hash_init(EG(active_symbol_table), 0, NULL, PVAL_PTR_DTOR, 0);
301+
if (object) {
302+
zval *dummy = (zval *) emalloc(sizeof(zval)), **this_ptr;
303+
304+
var_uninit(dummy);
305+
dummy->refcount=1;
306+
dummy->is_ref=0;
307+
zend_hash_update_ptr(EG(active_symbol_table), "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr);
308+
zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC);
309+
}
310310
original_return_value = EG(return_value);
311311
original_op_array = EG(active_op_array);
312312
EG(return_value) = retval;
313313
EG(active_op_array) = (zend_op_array *) function_state.function;
314314
original_opline_ptr = EG(opline_ptr);
315315
zend_execute(EG(active_op_array) ELS_CC);
316+
zend_hash_destroy(EG(active_symbol_table));
317+
efree(EG(active_symbol_table));
318+
EG(active_symbol_table) = calling_symbol_table;
316319
EG(active_op_array) = original_op_array;
317320
EG(return_value)=original_return_value;
318321
EG(opline_ptr) = original_opline_ptr;
319322
} else {
320323
((zend_internal_function *) function_state.function)->handler(param_count, retval, &EG(regular_list), &EG(persistent_list));
321324
}
322-
zend_hash_destroy(EG(active_symbol_table));
323-
efree(EG(active_symbol_table));
324-
EG(active_symbol_table) = calling_symbol_table;
325+
zend_ptr_stack_clear_multiple(ELS_C);
325326
EG(function_state_ptr) = original_function_state_ptr;
326327

327328
return SUCCESS;

0 commit comments

Comments
 (0)