diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | test/ruby/test_refinement.rb | 50 | ||||
-rw-r--r-- | version.h | 2 | ||||
-rw-r--r-- | vm_insnhelper.c | 8 | ||||
-rw-r--r-- | vm_method.c | 7 |
5 files changed, 74 insertions, 3 deletions
@@ -1,3 +1,13 @@ +Fri Oct 18 02:10:00 2013 Shugo Maeda <shugo@ruby-lang.org> + + * vm_insnhelper.c (vm_call_method): set ci->me to 0 when the + original method of a refined method is undef to avoid SEGV. + + * vm_method.c (rb_method_entry_without_refinements): return 0 when + the original method of a refined method is undef to avoid SEGV. + + * test/ruby/test_refinement.rb: related test. + Fri Oct 18 02:05:45 2013 Nobuyoshi Nakada <nobu@ruby-lang.org> * win32/file.c (rb_file_expand_path_internal): fix memory leaks at diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index b9d9c3e30d..2110221fc1 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -905,6 +905,56 @@ class TestRefinement < Test::Unit::TestCase INPUT end + def test_refine_undefed_method_and_call + assert_in_out_err([], <<-INPUT, ["NoMethodError"], []) + $VERBOSE = nil #to suppress warning "Refinements are experimental, ..." + class Foo + def foo + end + + undef foo + end + + module FooExt + refine Foo do + def foo + end + end + end + + begin + Foo.new.foo + rescue => e + p e.class + end + INPUT + end + + def test_refine_undefed_method_and_send + assert_in_out_err([], <<-INPUT, ["NoMethodError"], []) + $VERBOSE = nil #to suppress warning "Refinements are experimental, ..." + class Foo + def foo + end + + undef foo + end + + module FooExt + refine Foo do + def foo + end + end + end + + begin + Foo.new.send(:foo) + rescue => e + p e.class + end + INPUT + end + private def eval_using(mod, s) @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.0.0" #define RUBY_RELEASE_DATE "2013-10-18" -#define RUBY_PATCHLEVEL 336 +#define RUBY_PATCHLEVEL 337 #define RUBY_RELEASE_YEAR 2013 #define RUBY_RELEASE_MONTH 10 diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 9d321c0529..691f4d1030 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1840,7 +1840,13 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) no_refinement_dispatch: if (ci->me->def->body.orig_me) { ci->me = ci->me->def->body.orig_me; - goto normal_method_dispatch; + if (UNDEFINED_METHOD_ENTRY_P(ci->me)) { + ci->me = 0; + goto start_method_dispatch; + } + else { + goto normal_method_dispatch; + } } else { klass = ci->me->klass; diff --git a/vm_method.c b/vm_method.c index 41ddb2d1ac..f8cd2d9129 100644 --- a/vm_method.c +++ b/vm_method.c @@ -640,7 +640,12 @@ rb_method_entry_without_refinements(VALUE klass, ID id, } if (defined_class_ptr) *defined_class_ptr = defined_class; - return me; + if (UNDEFINED_METHOD_ENTRY_P(me)) { + return 0; + } + else { + return me; + } } static void |