]> granicus.if.org Git - php/commitdiff
Fix rope memory leaks upon exception
authorBob Weinand <bobwei9@hotmail.com>
Sun, 28 Jun 2015 13:42:05 +0000 (15:42 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Sun, 28 Jun 2015 13:42:15 +0000 (15:42 +0200)
Zend/zend_compile.c
Zend/zend_execute.c
ext/opcache/Optimizer/block_pass.c

index 7a776af1632b1740e15a8f61961056add260eae9..2e0822fdd420b660b820ec0928ba94e4ae93fd8a 100644 (file)
@@ -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;
index a77b29c6eff9ba9210247d0e3f5468be8b81154b..94636b52ee54e0fc5efb40b627096d584d289e3d 100644 (file)
@@ -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) {
index fe20248fee416f237d20400df14d701a1424d90e..8694b4b61aacdca31ba79e0044415b4faf558017 100644 (file)
@@ -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];