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:
parent
631c01f5ae
commit
e100fcbdd1
Notes:
git
2020-06-12 03:46:37 +09:00
2 changed files with 13 additions and 0 deletions
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue