ruby-changes:41155
From: ko1 <ko1@a...>
Date: Mon, 21 Dec 2015 18:41:20 +0900 (JST)
Subject: [ruby-changes:41155] ko1:r53228 (trunk): * gc.c (internal_object_p): should not expose singleton classes
ko1 2015-12-21 18:40:58 +0900 (Mon, 21 Dec 2015) New Revision: 53228 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53228 Log: * gc.c (internal_object_p): should not expose singleton classes without a metaclass. [Bug #11740] * class.c (rb_singleton_class_has_metaclass_p): added. * test/ruby/test_class.rb: add a test. Modified files: trunk/ChangeLog trunk/class.c trunk/gc.c trunk/test/ruby/test_class.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 53227) +++ ChangeLog (revision 53228) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Mon Dec 21 18:33:00 2015 Koichi Sasada <ko1@a...> + + * gc.c (internal_object_p): should not expose singleton classes + without a metaclass. + [Bug #11740] + + * class.c (rb_singleton_class_has_metaclass_p): added. + + * test/ruby/test_class.rb: add a test. + Mon Dec 21 12:15:32 2015 Kimura Wataru <kimuraw@i...> * test/ruby/test_io.rb: handled rlimit value same as r52277 Index: gc.c =================================================================== --- gc.c (revision 53227) +++ gc.c (revision 53228) @@ -2400,6 +2400,13 @@ internal_object_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/gc.c#L2400 case T_NODE: case T_ZOMBIE: break; + case T_CLASS: + { + if (FL_TEST(obj, FL_SINGLETON)) { + int rb_singleton_class_has_metaclass_p(VALUE sklass); + return rb_singleton_class_has_metaclass_p(obj) == 0; + } + } default: if (!p->as.basic.klass) break; return 0; Index: class.c =================================================================== --- class.c (revision 53227) +++ class.c (revision 53228) @@ -442,6 +442,12 @@ rb_singleton_class_attached(VALUE klass, https://github.com/ruby/ruby/blob/trunk/class.c#L442 */ #define META_CLASS_OF_CLASS_CLASS_P(k) (METACLASS_OF(k) == (k)) +int +rb_singleton_class_has_metaclass_p(VALUE sklass) +{ + return rb_attr_get(METACLASS_OF(sklass), id_attached) == sklass; +} + /*! * whether k has a metaclass * @retval 1 if \a k has a metaclass @@ -449,7 +455,13 @@ rb_singleton_class_attached(VALUE klass, https://github.com/ruby/ruby/blob/trunk/class.c#L455 */ #define HAVE_METACLASS_P(k) \ (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \ - rb_ivar_get(METACLASS_OF(k), id_attached) == (k)) + rb_singleton_class_has_metaclass_p(k)) + +int +rb_class_has_metaclass_p(VALUE klass) +{ + return HAVE_METACLASS_P(klass); +} /*! * ensures \a klass belongs to its own eigenclass. Index: test/ruby/test_class.rb =================================================================== --- test/ruby/test_class.rb (revision 53227) +++ test/ruby/test_class.rb (revision 53228) @@ -556,4 +556,24 @@ class TestClass < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_class.rb#L556 } end; end + + def test_should_not_expose_singleton_class_without_metaclass + assert_normal_exit %q{ + klass = Class.new(Array) + # The metaclass of +klass+ should handle #bla since it should inherit methods from meta:meta:Array + def (Array.singleton_class).bla; :bla; end + hidden = ObjectSpace.each_object(Class).find { |c| klass.is_a? c and c.inspect.include? klass.inspect } + raise unless hidden.nil? + }, '[Bug #11740]' + + assert_normal_exit %q{ + klass = Class.new(Array) + klass.singleton_class + # The metaclass of +klass+ should handle #bla since it should inherit methods from meta:meta:Array + def (Array.singleton_class).bla; :bla; end + hidden = ObjectSpace.each_object(Class).find { |c| klass.is_a? c and c.inspect.include? klass.inspect } + raise if hidden.nil? + }, '[Bug #11740]' + + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/