From: Bob Weinand Date: Sun, 28 Jun 2015 13:42:05 +0000 (+0200) Subject: Fix rope memory leaks upon exception X-Git-Tag: php-7.1.0alpha3~25^2~148 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a4529adb03a5e0d8c46809074a9bae37686e201;p=php Fix rope memory leaks upon exception --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7a776af163..2e0822fdd4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6622,6 +6622,11 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */ GET_NODE(result, opline->result); } else { uint32_t var; + zend_brk_cont_element *info = get_next_brk_cont_element(CG(active_op_array)); + info->brk = opline - CG(active_op_array)->opcodes; + info->start = rope_init_lineno; + info->parent = CG(context).current_brk_cont; + info->cont = -1; init_opline->extended_value = j; opline->opcode = ZEND_ROPE_END; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a77b29c6ef..94636b52ee 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2519,6 +2519,21 @@ static zend_always_inline void i_cleanup_unfinished_execution(zend_execute_data zend_hash_iterator_del(Z_FE_ITER_P(var)); } zval_ptr_dtor_nogc(var); + } else if (brk_opline->opcode == ZEND_ROPE_END) { + zend_string **rope = (zend_string **) EX_VAR(brk_opline->op1.var); + zend_op *last = EX(func)->op_array.opcodes + op_num; + while (last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT) { + ZEND_ASSERT(last >= EX(func)->op_array.opcodes); + last--; + } + if (last->opcode == ZEND_ROPE_INIT) { + zend_string_release(*rope); + } else { + int j = last->extended_value; + do { + zend_string_release(rope[j]); + } while (j--); + } } else if (brk_opline->opcode == ZEND_END_SILENCE) { /* restore previous error_reporting value */ if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) { diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index fe20248fee..8694b4b61a 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -208,6 +208,7 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz if (op_array->brk_cont_array[i].start >= 0 && (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE || op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FE_FREE || + op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_ROPE_END || op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) { int parent = op_array->brk_cont_array[i].parent; @@ -215,6 +216,7 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz op_array->brk_cont_array[parent].start < 0 && (op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FREE || op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FE_FREE || + op_array->opcodes[op_array->brk_cont_array[i].brk].opcode != ZEND_ROPE_END || op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_END_SILENCE)) { parent = op_array->brk_cont_array[parent].parent; } @@ -231,6 +233,7 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz if (op_array->brk_cont_array[i].start >= 0 && (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE || op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FE_FREE || + op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_ROPE_END || op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) { if (i != j) { op_array->brk_cont_array[j] = op_array->brk_cont_array[i];