From b563bcb7ff87b859ccdfa30f5d7c3f06cb26a239 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 27 Feb 2017 20:13:01 +0900 Subject: Check if OP_RETURN cross C function boundary; fix #3462 --- src/vm.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index 327cbc5f7..043983a05 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1669,18 +1669,26 @@ RETRY_TRY_BLOCK: /* Fall through to OP_R_NORMAL otherwise */ if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) { struct REnv *e = top_env(mrb, proc); + mrb_callinfo *ce; if (!MRB_ENV_STACK_SHARED_P(e)) { localjump_error(mrb, LOCALJUMP_ERROR_RETURN); goto L_RAISE; } - ci = mrb->c->cibase + e->cioff; - if (ci == mrb->c->cibase) { + + ce = mrb->c->cibase + e->cioff; + while (--ci > ce) { + if (ci->acc < 0) { + localjump_error(mrb, LOCALJUMP_ERROR_RETURN); + goto L_RAISE; + } + } + if (ce == mrb->c->cibase) { localjump_error(mrb, LOCALJUMP_ERROR_RETURN); goto L_RAISE; } mrb->c->stack = mrb->c->ci->stackent; - mrb->c->ci = ci; + mrb->c->ci = ce; break; } case OP_R_NORMAL: -- cgit v1.2.3