[#39548] [Bug #2291] Net::FTPでソケットをオープンする前にbinary=を呼び出すと落ちる — Akira Matsuda <redmine@...>

Bug #2291: Net::FTPでソケットをオープンする前にbinary=を呼び出すと落ちる

10 messages 2009/10/27

[#39592] infinite recursive call to C function — Yusuke ENDOH <mame@...>

遠藤です。

17 messages 2009/10/30
[#39596] Re: infinite recursive call to C function — Yukihiro Matsumoto <matz@...> 2009/10/30

まつもと ゆきひろです

[#39599] Re: infinite recursive call to C function — Nobuyoshi Nakada <nobu@...> 2009/11/02

なかだです。

[#39601] Re: infinite recursive call to C function — Yukihiro Matsumoto <matz@...> 2009/11/02

まつもと ゆきひろです

[ruby-dev:39591] Re: [ruby-cvs:32774] Ruby:r25556 (trunk): * array.c (rb_ary_to_ary): do not use #respond_to? to detect

From: Nobuyoshi Nakada <nobu@...>
Date: 2009-10-30 11:51:46 UTC
List: ruby-dev #39591
なかだです。

At Fri, 30 Oct 2009 18:40:53 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:39589]:
>   * method_missingが再定義されている時にはそれを呼ぶ。ちゃん
>     と動作するかどうかはよくわからない

こっちを実装してみました。


Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 25576)
+++ vm_eval.c	(working copy)
@@ -118,5 +118,5 @@ vm_call0(rb_thread_t* th, VALUE recv, VA
 	RB_GC_GUARD(new_args);
 	rb_ary_unshift(new_args, ID2SYM(id));
-	return rb_funcall2(recv, rb_intern("method_missing"),
+	return rb_funcall2(recv, idMethodMissing,
 			   argc+1, RARRAY_PTR(new_args));
       }
@@ -235,13 +235,15 @@ rb_call0(VALUE recv, ID mid, int argc, c
 }
 
-VALUE
-rb_check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
+static VALUE
+check_funcall(rb_method_entry_t *me, VALUE recv, ID mid, int argc, VALUE *argv)
 {
-    rb_method_entry_t *me = rb_search_method_emtry(recv, mid);
     rb_thread_t *th = GET_THREAD();
     int call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
 
     if (call_status != NOEX_OK) {
-	return Qundef;
+	me = rb_method_entry(CLASS_OF(recv), idMethodMissing);
+	if (!me || (me->flag & NOEX_BASIC) || !rb_obj_respond_to(recv, mid, TRUE))
+	    return Qundef;
+	return method_missing(recv, mid, argc, argv, call_status);
     }
     stack_check();
@@ -250,8 +252,13 @@ rb_check_funcall(VALUE recv, ID mid, int
 
 VALUE
+rb_check_funcall(VALUE recv, ID mid, int argc, VALUE *argv)
+{
+    return check_funcall(rb_search_method_emtry(recv, mid), recv, mid, argc, argv);
+}
+
+VALUE
 rb_funcall_no_recursive(VALUE recv, ID mid, int argc, VALUE *argv, VALUE (*func)())
 {
     rb_method_entry_t *me = rb_search_method_emtry(recv, mid);
-    rb_thread_t *th = GET_THREAD();
     int call_status;
 
@@ -260,10 +267,5 @@ rb_funcall_no_recursive(VALUE recv, ID m
 	me->def->body.cfunc.func == func)
 	return Qundef;
-    call_status = rb_method_call_status(th, me, CALL_FCALL, Qundef);
-    if (call_status != NOEX_OK) {
-	return Qundef;
-    }
-    stack_check();
-    return vm_call0(th, recv, mid, argc, argv, me);
+    return check_funcall(rb_search_method_emtry(recv, mid), recv, mid, argc, argv);
 }
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread