From: Kazuhiro NISHIYAMA Date: 2008-11-25T15:57:06+09:00 Subject: [ruby-dev:37182] [Bug:1.8] RSTRING in ext/gdbm/gdbm.c 西山和広です。 [ruby-core:20082]にひっかかったので、とりあえず Index: object.c =================================================================== --- object.c(revision 20352) +++ object.c(working copy) @@ -223,7 +223,7 @@ } clone = rb_obj_alloc(rb_obj_class(obj)); RBASIC(clone)->klass = rb_singleton_class_clone(obj); - RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE); + RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT|ELTS_SHARED)) & ~(FL_FREEZE|FL_FINALIZE); init_copy(clone, obj); RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE; として回避してみたところ、gdbmのテストの中で落ちるようになったので、 調べてみたところ、rb_str_s_allocでELTS_SHAREDが設定されているのに aux.sharedを無視してaux.capaを設定していて、それを後で RSTRING(aux.shared)で参照されてしまうのが原因だとわかりました。 以下のようにした方が良いと思ったのですが、どうでしょうか? Index: ext/gdbm/gdbm.c =================================================================== --- ext/gdbm/gdbm.c(revision 20352) +++ ext/gdbm/gdbm.c(working copy) @@ -303,12 +303,7 @@ if (val.dptr == 0) return Qnil; - str = rb_obj_alloc(rb_cString); - RSTRING(str)->len = val.dsize; - RSTRING(str)->aux.capa = val.dsize; - RSTRING(str)->ptr = REALLOC_N(val.dptr,char,val.dsize+1); - RSTRING(str)->ptr[val.dsize] = '\0'; - + str = rb_str_new(val.dptr, val.dsize); OBJ_TAINT(str); return (VALUE)str; } @@ -349,12 +344,7 @@ if (key.dptr == 0) return Qnil; - str = rb_obj_alloc(rb_cString); - RSTRING(str)->len = key.dsize; - RSTRING(str)->aux.capa = key.dsize; - RSTRING(str)->ptr = REALLOC_N(key.dptr,char,key.dsize+1); - RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; - + str = rb_str_new(key.dptr, key.dsize); OBJ_TAINT(str); return str; } @@ -373,12 +363,7 @@ if (key2.dptr == 0) return Qnil; - str = rb_obj_alloc(rb_cString); - RSTRING(str)->len = key2.dsize; - RSTRING(str)->aux.capa = key2.dsize; - RSTRING(str)->ptr = REALLOC_N(key2.dptr,char,key2.dsize+1); - RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; - + str = rb_str_new(key2.dptr, key2.dsize); OBJ_TAINT(str); return str; } -- |ZnZ(ゼット エヌ ゼット) |西山和広(Kazuhiro NISHIYAMA)