diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-12-25 20:01:55 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-12-25 21:31:10 +0900 |
| commit | 0b2d54f4f1d66a0b00625dcc634966d67c29b8b8 (patch) | |
| tree | fb34f7702c2654160b4a34b639b147df2a116d91 /include | |
| parent | d4cbe6271cc8343647fd0841bb549e1b7c804c34 (diff) | |
| download | mruby-0b2d54f4f1d66a0b00625dcc634966d67c29b8b8.tar.gz mruby-0b2d54f4f1d66a0b00625dcc634966d67c29b8b8.zip | |
Fix potentially use of wrong method cache
#### Example (with `MRB_METHOD_CACHE`)
```ruby
GC.start
c = Class.new
p c #=> #<Class:0x7fd6a180e790>
c.new #=> cache `c.new`
c = nil
GC.start #=> `c` is GCed
r = Range.dup
p r #=> #<Class:0x7fd6a180e790>
# [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.
Diffstat (limited to 'include')
| -rw-r--r-- | include/mruby/class.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/mruby/class.h b/include/mruby/class.h index c15633e83..cbf96fef2 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -95,6 +95,12 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); void mrb_gc_free_mt(mrb_state*, struct RClass*); +#ifdef MRB_METHOD_CACHE +void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c); +#else +#define mrb_mc_clear_by_class(mrb,c) +#endif + MRB_END_DECL #endif /* MRUBY_CLASS_H */ |
