summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--test/ruby/test_refinement.rb50
-rw-r--r--version.h2
-rw-r--r--vm_insnhelper.c8
-rw-r--r--vm_method.c7
5 files changed, 74 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 86f46a2834..212905a307 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
diff --git a/version.h b/version.h
index cbd6b3cecb..1282fad84c 100644
--- a/version.h
+++ b/version.h
@@ -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