diff options
author | Jean byroot Boussier <jean.boussier+github@shopify.com> | 2022-12-01 23:32:41 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-01 17:32:41 -0500 |
commit | 3d272b0fc822f5c2e9c716377b7fcecf15426b27 (patch) | |
tree | 71b970741b78968c45d9aa5758c616948148ab69 /test/ruby | |
parent | 9da2a5204f32a4f2ce135fddde2abb6e07d647e9 (diff) | |
download | ruby-3d272b0fc822f5c2e9c716377b7fcecf15426b27.tar.gz |
Module#remove_method: Check frozen on the right object
Previously, the frozen check happened on `RCLASS_ORIGIN(self)`, which
can return an iclass. The frozen check is supposed to respond to objects
that users can call methods on while iclasses are hidden from users.
Other mutation methods like Module#{define_method,alias_method,public}
don't do this. Check frozen status on the module itself.
Fixes [Bug #19164] and [Bug #19166].
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Diffstat (limited to 'test/ruby')
-rw-r--r-- | test/ruby/test_class.rb | 9 | ||||
-rw-r--r-- | test/ruby/test_module.rb | 12 |
2 files changed, 21 insertions, 0 deletions
diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb index 8d9fde144e..5086e60398 100644 --- a/test/ruby/test_class.rb +++ b/test/ruby/test_class.rb @@ -809,4 +809,13 @@ PREP 3_000_000.times(&code) CODE end + + def test_instance_freeze_dont_freeze_the_class_bug_19164 + klass = Class.new + klass.prepend(Module.new) + + klass.new.freeze + klass.define_method(:bar) {} + assert_equal klass, klass.remove_method(:bar), '[Bug #19164]' + end end diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 981c1394a2..6c4defd6b1 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -2350,6 +2350,18 @@ class TestModule < Test::Unit::TestCase assert_equal(:foo, removed) end + def test_frozen_prepend_remove_method + [Module, Class].each do |klass| + mod = klass.new do + prepend(Module.new) + def foo; end + end + mod.freeze + assert_raise(FrozenError, '[Bug #19166]') { mod.send(:remove_method, :foo) } + assert_equal([:foo], mod.instance_methods(false)) + end + end + def test_prepend_class_ancestors bug6658 = '[ruby-core:45919]' m = labeled_module("m") |