[#14922] alias $gvar — Koji Arai <JCA02266@...>

新井です。

19 messages 2001/10/14

[#15006] Re: eval.c (rb_stack_check): prohibit recursive raising error — WATANABE Hirofumi <eban@...>

わたなべです。

13 messages 2001/10/26
[#15008] Re: eval.c (rb_stack_check): prohibit recursive raising error — Shugo Maeda <shugo@...> 2001/10/26

前田です。

[ruby-dev:14945] Re: [BUG] SEGV: module_eval

From: nobu.nakada@...
Date: 2001-10-16 05:17:29 UTC
List: ruby-dev #14945
なかだです。

At Tue, 16 Oct 2001 11:46:24 +0900,
Satoru Takabayashi <satoru@namazu.org> wrote:
> こんなことする方が悪いという気がしますが、次のコードを実行す
> ると segmentation fault が起きることがわかりました。

 ようするに、method_missingでundefされたinspectを呼び出して、
無限に再帰してしまうということですね。とりあえずinspectやto_sを
トラップしてみましたが、いまいち。どっちかというとstack_check()
の方が有効かも。

> ちなみに、happy-dispatch == hara-kiri です。

 おお。happyなのか。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.137.2.67
diff -u -2 -p -r1.137.2.67 eval.c
--- eval.c	2001/10/09 15:03:19	1.137.2.67
+++ eval.c	2001/10/16 05:11:30
@@ -435,6 +435,6 @@ rb_method_boundp(klass, id, ex)
 }
 
-static ID init, eqq, each, aref, aset, match, to_ary;
-static ID missing, added, singleton_added;
+static ID init, eqq, each, aref, aset, match, to_ary, to_s;
+static ID missing, added, singleton_added, inspect;
 static ID __id__, __send__;
 
@@ -4066,4 +4066,6 @@ rb_f_missing(argc, argv, obj)
     }
 
+    rb_stack_check();
+
     id = SYM2ID(argv[0]);
     argc--; argv++;
@@ -4079,9 +4081,16 @@ rb_f_missing(argc, argv, obj)
 	format = "undefined method `%s' for false";
 	break;
-      case T_OBJECT:
-	d = rb_any_to_s(obj);
-	break;
       default:
-	d = rb_inspect(obj);
+	if (id == inspect || id == to_s) {
+	    desc = "uninspectable object";
+	    d = Qnil;
+	    break;
+	}
+	if (TYPE(obj) == T_OBJECT) {
+	    d = rb_any_to_s(obj);
+	}
+	else {
+	    d = rb_inspect(obj);
+	}
 	break;
     }
@@ -4103,8 +4112,10 @@ rb_f_missing(argc, argv, obj)
 	    format = "undefined method `%s' for %s%s%s";
 	}
-	if (RSTRING(d)->len > 65) {
-	    d = rb_any_to_s(obj);
+	if (!NIL_P(d)) {
+	    if (RSTRING(d)->len > 65) {
+		d = rb_any_to_s(obj);
+	    }
+	    desc = RSTRING(d)->ptr;
 	}
-	desc = RSTRING(d)->ptr;
     }
 
@@ -4190,4 +4201,12 @@ stack_length(p)
 }
 
+void
+rb_stack_check()
+{
+    if (stack_length(0) > STACK_LEVEL_MAX) {
+	rb_raise(rb_eSysStackError, "stack level too deep");
+    }
+}
+
 static VALUE
 call_cfunc(func, recv, len, argc, argv)
@@ -4305,7 +4324,5 @@ rb_call0(klass, recv, id, argc, argv, bo
     if ((++tick & 0xff) == 0) {
 	CHECK_INTS;		/* better than nothing */
-	if (stack_length(0) > STACK_LEVEL_MAX) {
-	    rb_raise(rb_eSysStackError, "stack level too deep");
-	}
+	rb_stack_check();
     }
     PUSH_ITER(itr);
@@ -5903,6 +5920,8 @@ Init_eval()
     match = rb_intern("=~");
     to_ary = rb_intern("to_ary");
+    to_s = rb_intern("to_s");
     missing = rb_intern("method_missing");
     added = rb_intern("method_added");
+    inspect = rb_intern("inspect");
     singleton_added = rb_intern("singleton_method_added");
 
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.35.2.8
diff -u -2 -p -r1.35.2.8 intern.h
--- intern.h	2001/10/02 04:25:52	1.35.2.8
+++ intern.h	2001/10/16 04:46:58
@@ -116,4 +116,5 @@ void rb_error_frozen _((char*)) NORETURN
 void rb_exc_raise _((VALUE)) NORETURN;
 void rb_exc_fatal _((VALUE)) NORETURN;
+void rb_stack_check _((void));
 void rb_remove_method _((VALUE, const char*));
 void rb_disable_super _((VALUE, const char*));


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

In This Thread