From c2a04d87d0f51e871e2fc0254ce6f90136b50169 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 23 Apr 2015 02:35:58 +0000 Subject: vm_eval.c: allow symbols to instance_eval/exec * vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow symbols to just instance_eval/exec, execept for definition of singletons. [ruby-core:68961] [Bug #11086] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ class.c | 9 +++++---- test/ruby/test_symbol.rb | 29 +++++++++++++++++++++++++++++ vm_eval.c | 32 ++++++++++++++++---------------- 4 files changed, 56 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7aacfb4cb0..01e9aafcb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Apr 23 11:35:55 2015 Nobuyoshi Nakada + + * vm_eval.c (rb_obj_instance_eval, rb_obj_instance_exec): allow + symbols to just instance_eval/exec, execept for definition of + singletons. [ruby-core:68961] [Bug #11086] + Thu Apr 23 10:01:36 2015 SHIBATA Hiroshi * lib/delegate.rb: fix a typo. diff --git a/class.c b/class.c index 11210682fe..37ad4b542b 100644 --- a/class.c +++ b/class.c @@ -1539,7 +1539,8 @@ singleton_class_of(VALUE obj) { VALUE klass; - if (FIXNUM_P(obj) || FLONUM_P(obj) || SYMBOL_P(obj)) { + if (FIXNUM_P(obj) || FLONUM_P(obj) || STATIC_SYM_P(obj)) { + no_singleton: rb_raise(rb_eTypeError, "can't define singleton"); } if (SPECIAL_CONST_P(obj)) { @@ -1549,9 +1550,9 @@ singleton_class_of(VALUE obj) return klass; } else { - enum ruby_value_type type = BUILTIN_TYPE(obj); - if (type == T_FLOAT || type == T_BIGNUM) { - rb_raise(rb_eTypeError, "can't define singleton"); + switch (BUILTIN_TYPE(obj)) { + case T_FLOAT: case T_BIGNUM: case T_SYMBOL: + goto no_singleton; } } diff --git a/test/ruby/test_symbol.rb b/test/ruby/test_symbol.rb index 66c62cb298..0a055db2c9 100644 --- a/test/ruby/test_symbol.rb +++ b/test/ruby/test_symbol.rb @@ -199,6 +199,35 @@ class TestSymbol < Test::Unit::TestCase assert_raise(TypeError) { a = :foo; def a.foo; end } end + SymbolsForEval = [ + :foo, + "dynsym_#{Random.rand(10000)}_#{Time.now}".to_sym + ] + + def test_instance_eval + bug11086 = '[ruby-core:68961] [Bug #11086]' + SymbolsForEval.each do |sym| + assert_nothing_raised(TypeError, sym, bug11086) { + sym.instance_eval {} + } + assert_raise(TypeError, sym, bug11086) { + sym.instance_eval {def foo; end} + } + end + end + + def test_instance_exec + bug11086 = '[ruby-core:68961] [Bug #11086]' + SymbolsForEval.each do |sym| + assert_nothing_raised(TypeError, sym, bug11086) { + sym.instance_exec {} + } + assert_raise(TypeError, sym, bug11086) { + sym.instance_exec {def foo; end} + } + end + end + def test_frozen_symbol assert_equal(true, :foo.frozen?) assert_equal(true, :each.frozen?) diff --git a/vm_eval.c b/vm_eval.c index b63eec262e..281dbe77cc 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1627,6 +1627,20 @@ specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self) } } +static VALUE +singleton_class_for_eval(VALUE self) +{ + if (SPECIAL_CONST_P(self)) { + return rb_special_singleton_class(self); + } + switch (BUILTIN_TYPE(self)) { + case T_FLOAT: case T_BIGNUM: case T_SYMBOL: + return Qnil; + default: + return rb_singleton_class(self); + } +} + /* * call-seq: * obj.instance_eval(string [, filename [, lineno]] ) -> obj @@ -1663,14 +1677,7 @@ specific_eval(int argc, const VALUE *argv, VALUE klass, VALUE self) VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self) { - VALUE klass; - - if (SPECIAL_CONST_P(self)) { - klass = rb_special_singleton_class(self); - } - else { - klass = rb_singleton_class(self); - } + VALUE klass = singleton_class_for_eval(self); return specific_eval(argc, argv, klass, self); } @@ -1695,14 +1702,7 @@ rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self) VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self) { - VALUE klass; - - if (SPECIAL_CONST_P(self)) { - klass = rb_special_singleton_class(self); - } - else { - klass = rb_singleton_class(self); - } + VALUE klass = singleton_class_for_eval(self); return yield_under(klass, self, rb_ary_new4(argc, argv)); } -- cgit v1.2.3