summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2018-10-02 17:26:43 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2018-10-02 17:26:43 +0900
commit8392578216548c01713319df199c7344e056ba24 (patch)
tree00038d2b6cd3a6b7eda9e99c98887f78b0d0e24b /mrbgems/mruby-eval/src
parente6841abad69df4d20e359e0b1c2eb190696ec0c4 (diff)
downloadmruby-8392578216548c01713319df199c7344e056ba24.tar.gz
mruby-8392578216548c01713319df199c7344e056ba24.zip
Fixed SEGV from `eval` called form top-level `mrb_funcall()`; fix #4028
Diffstat (limited to 'mrbgems/mruby-eval/src')
-rw-r--r--mrbgems/mruby-eval/src/eval.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index b9c87f6d1..e6a82723d 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -226,7 +226,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
struct mrb_parser_state *p;
struct RProc *proc;
struct REnv *e;
- mrb_callinfo *ci = &mrb->c->ci[-1]; /* callinfo of eval caller */
+ mrb_callinfo *ci; /* callinfo of eval caller */
struct RClass *target_class = NULL;
int bidx;
@@ -276,8 +276,16 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
mrbc_context_free(mrb, cxt);
mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
}
- target_class = MRB_PROC_TARGET_CLASS(ci->proc);
- if (!MRB_PROC_CFUNC_P(ci->proc)) {
+ if (mrb->c->ci > mrb->c->cibase) {
+ ci = &mrb->c->ci[-1];
+ }
+ else {
+ ci = mrb->c->cibase;
+ }
+ if (ci->proc) {
+ target_class = MRB_PROC_TARGET_CLASS(ci->proc);
+ }
+ if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
if (ci->env) {
e = ci->env;
}
@@ -315,10 +323,12 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
/* no argument passed from eval() */
mrb->c->ci->argc = 0;
if (mrb->c->ci->acc < 0) {
+ ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase;
mrb_value ret = mrb_top_run(mrb, proc, self, 0);
if (mrb->exc) {
mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
}
+ mrb->c->ci = mrb->c->cibase + cioff;
return ret;
}
/* clear block */