From 81f98a39258a361dc454f72450c0055bdea6963f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 19 Sep 2022 08:29:23 +0900 Subject: [PATCH] vm.c (cipop): check type of the callinfo::blk; fix #5791 Since `callinfo::blk` is not marked in the GC, it may be reclaimed in the sweep phase. When it reclaimed, it will become either (a) a non Proc object, or (b) a Proc object that happen to have the same address. For case (a), adding `b->tt == MRB_TT_PROC` check works. We should avoid the following `MRB_PROC_STRICT_P()` and `MRB_PROC_ENV()` operations for non Proc objects. For case (b), `MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])` check should work. Unrelated Proc objects should be filtered by the check. We don't need to clear `callinfo::blk` by `NULL` because the callinfo struct will be discarded afterward in the `cipop()` function. --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index 379f35492..4b81878a6 100644 --- a/src/vm.c +++ b/src/vm.c @@ -410,7 +410,7 @@ cipop(mrb_state *mrb) mrb_vm_ci_env_set(c->ci, NULL); // make possible to free by GC if env is not needed struct RProc *b = c->ci->blk; - if (b && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])) { + if (b && b->tt == MRB_TT_PROC && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&c->ci[-1])) { b->flags |= MRB_PROC_ORPHAN; } if (env && !mrb_env_unshare(mrb, env, TRUE)) {