From 37102f6bdba6ca819dc96fc13ebc44087115ec08 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 4 Mar 2017 14:37:22 +0000 Subject: compile.c: memory leak * compile.c (iseq_set_sequence): fix potential memory leaks on an invalid instruction sequence. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- compile.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 5d838b7ac7..6fd0c2a2fd 100644 --- a/compile.c +++ b/compile.c @@ -1642,6 +1642,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) list = FIRST_ELEMENT(anchor); line_info_index = code_index = sp = 0; +#define BADINSN_ERROR \ + (dump_disasm_list(list), \ + xfree(generated_iseq), \ + xfree(line_info_table), \ + COMPILE_ERROR) + while (list) { switch (list->type) { case ISEQ_ELEMENT_INSN: @@ -1653,6 +1659,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) /* update sp */ sp = calc_sp_depth(sp, iobj); + if (sp < 0) { + BADINSN_ERROR(iseq, iobj->line_no, + "argument stack underflow (%d)", sp); + return COMPILE_NG; + } if (sp > stack_max) { stack_max = sp; } @@ -1667,10 +1678,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) /* operand check */ if (iobj->operand_size != len - 1) { /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */ - dump_disasm_list(list); - xfree(generated_iseq); - xfree(line_info_table); - COMPILE_ERROR(iseq, iobj->line_no, + BADINSN_ERROR(iseq, iobj->line_no, "operand size miss! (%d for %d)", iobj->operand_size, len - 1); return COMPILE_NG; @@ -1685,7 +1693,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) /* label(destination position) */ LABEL *lobj = (LABEL *)operands[j]; if (!lobj->set) { - COMPILE_ERROR(iseq, iobj->line_no, + BADINSN_ERROR(iseq, iobj->line_no, "unknown label"); return COMPILE_NG; } @@ -1778,9 +1786,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) generated_iseq[code_index + 1 + j] = operands[j]; break; default: - xfree(generated_iseq); - xfree(line_info_table); - COMPILE_ERROR(iseq, iobj->line_no, + BADINSN_ERROR(iseq, iobj->line_no, "unknown operand type: %c", type); return COMPILE_NG; } @@ -1855,6 +1861,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) iseq->body->iseq_size = code_index; iseq->body->stack_max = stack_max; + /* get rid of memory leak when REALLOC failed */ + iseq->body->line_info_table = line_info_table; + REALLOC_N(line_info_table, struct iseq_line_info_entry, line_info_index); iseq->body->line_info_table = line_info_table; iseq->body->line_info_size = line_info_index; -- cgit v1.2.3