From: nobu@... Date: 2004-09-15T14:29:09+09:00 Subject: [ruby-dev:24271] Re: Array#assoc dumps core なかだです。 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はできる。 中田 伸悦