1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Prohibit setting class variable on frozen module through inheritance

Setting class varibles goes through the ancestor list which can
contain iclasses. Iclasses share a lot of information with the
module they are made from, but not the frozen status.

Check the frozen status of the module instead of the iclass.
This commit is contained in:
Alan Wu 2020-06-10 18:44:52 -04:00
parent 631c01f5ae
commit e100fcbdd1
Notes: git 2020-06-12 03:46:37 +09:00
2 changed files with 13 additions and 0 deletions

View file

@ -35,6 +35,16 @@ class TestVariable < Test::Unit::TestCase
end
end
def test_setting_class_variable_on_module_through_inheritance
mod = Module.new
mod.class_variable_set(:@@foo, 1)
mod.freeze
c = Class.new { include(mod) }
assert_raise(FrozenError) { c.class_variable_set(:@@foo, 2) }
assert_raise(FrozenError) { c.class_eval("@@foo = 2") }
assert_equal(1, c.class_variable_get(:@@foo))
end
def test_singleton_class_included_class_variable
c = Class.new
c.extend(Olympians)

View file

@ -3143,6 +3143,9 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
target = tmp;
}
if (RB_TYPE_P(target, T_ICLASS)) {
target = RBASIC(target)->klass;
}
check_before_mod_set(target, id, val, "class variable");
if (!RCLASS_IV_TBL(target)) {
RCLASS_IV_TBL(target) = st_init_numtable();