diff options
| author | KOBAYASHI Shuji <[email protected]> | 2019-04-24 21:05:44 +0900 |
|---|---|---|
| committer | KOBAYASHI Shuji <[email protected]> | 2019-04-24 21:05:44 +0900 |
| commit | 4720648137f2698cceb635c251475dec645cd598 (patch) | |
| tree | 535584bbc083956801dd6c8c702c8dfe8c4c44d9 | |
| parent | 163a6d01e035f16b15d3b08c0dfddd2caec09f9b (diff) | |
| download | mruby-4720648137f2698cceb635c251475dec645cd598.tar.gz mruby-4720648137f2698cceb635c251475dec645cd598.zip | |
Fix modiying class variable to frozen class/module
| -rw-r--r-- | mrbgems/mruby-metaprog/test/metaprog.rb | 8 | ||||
| -rw-r--r-- | src/variable.c | 2 | ||||
| -rw-r--r-- | test/t/class.rb | 19 |
3 files changed, 28 insertions, 1 deletions
diff --git a/mrbgems/mruby-metaprog/test/metaprog.rb b/mrbgems/mruby-metaprog/test/metaprog.rb index 1262c9945..0abeb90a6 100644 --- a/mrbgems/mruby-metaprog/test/metaprog.rb +++ b/mrbgems/mruby-metaprog/test/metaprog.rb @@ -171,7 +171,6 @@ assert('Module#class_variable_set', '15.2.2.4.18') do @@foo end end - assert_equal 99, Test4ClassVariableSet.class_variable_set(:@@cv, 99) assert_equal 101, Test4ClassVariableSet.class_variable_set(:@@foo, 101) assert_true Test4ClassVariableSet.class_variables.include? :@@cv @@ -180,6 +179,13 @@ assert('Module#class_variable_set', '15.2.2.4.18') do %w[@@ @@1 @@x= @x @ x 1].each do |n| assert_raise(NameError) { Test4ClassVariableSet.class_variable_set(n, 1) } end + + m = Module.new.freeze + assert_raise(FrozenError) { m.class_variable_set(:@@cv, 1) } + + parent = Class.new{ class_variable_set(:@@a, nil) }.freeze + child = Class.new(parent) + assert_raise(FrozenError) { child.class_variable_set(:@@a, 1) } end assert('Module#class_variables', '15.2.2.4.19') do diff --git a/src/variable.c b/src/variable.c index 983fe52f7..c4c9d369f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -671,6 +671,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) iv_tbl *t = c->iv; if (iv_get(mrb, t, sym, NULL)) { + mrb_check_frozen(mrb, c); iv_put(mrb, t, sym, v); mrb_write_barrier(mrb, (struct RBasic*)c); return; @@ -698,6 +699,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) c = cls; } + mrb_check_frozen(mrb, c); if (!c->iv) { c->iv = iv_new(mrb); } diff --git a/test/t/class.rb b/test/t/class.rb index 290ecf74a..0c95677fc 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -433,6 +433,25 @@ assert('overriding class variable with a module (#3235)') do end end +assert('class variable for frozen class/module') do + module CVarForFrozenModule + freeze + assert_raise(FrozenError) { @@cv = 1 } + end + + class CVarForFrozenClassA + @@a = nil + freeze + end + class CVarForFrozenClassB < CVarForFrozenClassA + def a=(v) + @@a = v + end + end + b = CVarForFrozenClassB.new + assert_raise(FrozenError) { b.a = 1 } +end + assert('class with non-class/module outer raises TypeError') do assert_raise(TypeError) { class 0::C1; end } assert_raise(TypeError) { class []::C2; end } |
