From c7c9543bed57db12fd8aa57391e0b652ee27cb23 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 28 Oct 2017 21:09:25 +0900 Subject: Fixed UPVAR gotchas; fix #3835 Both `uvenv` function and `env` generation in `create_proc_from_string` function have bugs to handling enclosed environment objects. --- src/vm.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/vm.c b/src/vm.c index 9758ccf1e..b1e2b624b 100644 --- a/src/vm.c +++ b/src/vm.c @@ -217,13 +217,24 @@ uvenv(mrb_state *mrb, int up) struct RProc *proc = mrb->c->ci->proc; struct REnv *e; - do { - e = MRB_PROC_ENV(proc); - if (!e) return NULL; + while (up--) { proc = proc->upper; if (!proc) return NULL; - } while (up--); - return e; + } + e = MRB_PROC_ENV(proc); + if (e) return e; /* proc has enclosed env */ + else { + mrb_callinfo *ci = mrb->c->ci; + mrb_callinfo *cb = mrb->c->cibase; + + while (cb <= ci) { + if (ci->proc == proc) { + return ci->env; + } + ci--; + } + } + return NULL; } static inline struct RProc* -- cgit v1.2.3