diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-02-27 20:13:01 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-02-27 20:13:01 +0900 |
| commit | b563bcb7ff87b859ccdfa30f5d7c3f06cb26a239 (patch) | |
| tree | 21d634f9ed57233480eca76a4f5ebb8e2c8162ee | |
| parent | 50bbdbb11b1cecd2843db2825cab4081893047c1 (diff) | |
| download | mruby-b563bcb7ff87b859ccdfa30f5d7c3f06cb26a239.tar.gz mruby-b563bcb7ff87b859ccdfa30f5d7c3f06cb26a239.zip | |
Check if OP_RETURN cross C function boundary; fix #3462
| -rw-r--r-- | src/vm.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -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: |
