[ruby-dev:24271] Re: Array#assoc dumps core

From: nobu@...
Date: 2004-09-15 05:29:09 UTC
List: ruby-dev #24271
なかだです。

At Wed, 15 Sep 2004 12:30:27 +0900,
Tanaka Akira wrote in [ruby-dev:24269]:
> 次のようにすると core を吐きます。
> 
> % ./ruby -e '
> len = 100000
> arr = [[nil, nil]] * len
> o = Object.new
> class << o; self end.__send__(:define_method, :==) {
>   arr.clear
>   arr.compact!
>   false
> }
> arr[100][0] = o
> p arr.assoc(true)
> '
> -e:11: [BUG] Segmentation fault
> ruby 1.9.0 (2004-09-14) [i686-linux]

> # これが最後のはずがない

rassocもですね。あとはRARRAY()->ptrを取り出したままメソッドを呼
んだりyieldしたりしているものはなさそうに見えます。


Index: array.c
===================================================================
RCS file: /cvs/ruby/src/ruby/array.c,v
retrieving revision 1.154
diff -u -2 -p -r1.154 array.c
--- array.c	24 Jul 2004 09:48:21 -0000	1.154
+++ array.c	15 Sep 2004 05:26:21 -0000
@@ -2468,15 +2468,13 @@ rb_ary_assoc(ary, key)
     VALUE ary, key;
 {
-    VALUE *p, *pend;
+    long i;
+    VALUE v;
 
-    p = RARRAY(ary)->ptr;
-    pend = p + RARRAY(ary)->len;
-    
-    while (p < pend) {
-	if (TYPE(*p) == T_ARRAY &&
-		RARRAY(*p)->len > 0 &&
-		rb_equal(RARRAY(*p)->ptr[0], key))
-	    return *p;
-	p++;
+    for (i = 0; i < RARRAY(ary)->len; ++i) {
+	v = RARRAY(ary)->ptr[i];
+	if (TYPE(v) == T_ARRAY &&
+	    RARRAY(v)->len > 0 &&
+	    rb_equal(RARRAY(v)->ptr[0], key))
+	    return v;
     }
     return Qnil;
@@ -2501,15 +2499,13 @@ rb_ary_rassoc(ary, value)
     VALUE ary, value;
 {
-    VALUE *p, *pend;
-
-    p = RARRAY(ary)->ptr;
-    pend = p + RARRAY(ary)->len;
+    long i;
+    VALUE v;
 
-    while (p < pend) {
-	if (TYPE(*p) == T_ARRAY
-	    && RARRAY(*p)->len > 1
-	    && rb_equal(RARRAY(*p)->ptr[1], value))
-	    return *p;
-	p++;
+    for (i = 0; i < RARRAY(ary)->len; ++i) {
+	v = RARRAY(ary)->ptr[i];
+	if (TYPE(v) == T_ARRAY &&
+	    RARRAY(v)->len > 1 &&
+	    rb_equal(RARRAY(v)->ptr[1], value))
+	    return v;
     }
     return Qnil;


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

In This Thread

Prev Next