From 0b2d54f4f1d66a0b00625dcc634966d67c29b8b8 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 25 Dec 2019 20:01:55 +0900 Subject: Fix potentially use of wrong method cache #### Example (with `MRB_METHOD_CACHE`) ```ruby GC.start c = Class.new p c #=> # c.new #=> cache `c.new` c = nil GC.start #=> `c` is GCed r = Range.dup p r #=> # # [same pointer as `c`] r.new(2, 3) #=> ArgumentError: 'initialize': # wrong number of arguments (2 for 0) # [`c.new` is called instead of `r.new`] ``` #### Cause An entry of method cache is identified by class pointer and method id. However, reusing memory after GC may create a class with the same pointer as the cached class. #### Treatment Cleared method caches of the class when the class is GCed. --- src/gc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/gc.c') diff --git a/src/gc.c b/src/gc.c index 40c85a373..8d9a1806c 100644 --- a/src/gc.c +++ b/src/gc.c @@ -807,10 +807,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) case MRB_TT_SCLASS: mrb_gc_free_mt(mrb, (struct RClass*)obj); mrb_gc_free_iv(mrb, (struct RObject*)obj); + mrb_mc_clear_by_class(mrb, (struct RClass*)obj); break; case MRB_TT_ICLASS: if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) mrb_gc_free_mt(mrb, (struct RClass*)obj); + mrb_mc_clear_by_class(mrb, (struct RClass*)obj); break; case MRB_TT_ENV: { -- cgit v1.2.3