From: Nobuyoshi Nakada Date: 2007-12-06T20:36:28+09:00 Subject: [ruby-dev:32472] Re: `split': negative string size (or size too big) (ArgumentError) なかだです。 At Tue, 4 Dec 2007 20:17:55 +0900, Nobuyoshi Nakada wrote in [ruby-dev:32453]: > At Tue, 4 Dec 2007 17:52:27 +0900, > Tanaka Akira wrote in [ruby-dev:32452]: > > "あいうえお".force_encoding("euc-jp").split(//) と (EUC-JP > > で) 行うと negative string size となります。 > > > > % ./ruby -ve 'p "あいうえお".force_encoding("euc-jp").split(//)' > > ruby 1.9.0 (2007-12-04 patchlevel 0) [i686-linux] > > -e:1:in `split': negative string size (or size too big) (ArgumentError) > > from -e:1:in `
' これ以外にも、 p "あいうえお".partition("う") #=> ["あい", "う", "お"] # -*- encoding: shift_jis -*- p "表示".partition("\\") #=> ["表", "\\", ""] とかいろいろおかしなことになってるので、byte/char offsetの使いわ けに関してはもっと見直す必要がありそうです。 > rb_reg_search()が文字単位の位置を返すのに、rb_str_split_m()では > byte位置として使っているためですね。BEG()やEND()もbyte位置のまま > なので、メソッドの戻り値として返すときに文字位置に変換するように > したほうがいいのではないでしょうか。 とりあえずこっちだけ。 Index: re.c =================================================================== --- re.c (resuult 14122) +++ re.c (working copy) @@ -865,5 +865,5 @@ rb_reg_search(VALUE re, VALUE str, int p OBJ_INFECT(match, str); - return rb_str_sublen(RMATCH(match)->str, result); + return result; } @@ -1836,10 +1836,10 @@ reg_operand(VALUE s, int check) } -static VALUE +static long rb_reg_match_pos(VALUE re, VALUE str, long pos) { if (NIL_P(str)) { rb_backref_set(Qnil); - return Qnil; + return -1; } str = reg_operand(str, Qtrue); @@ -1848,5 +1848,5 @@ rb_reg_match_pos(VALUE re, VALUE str, lo pos += RSTRING_LEN(str); if (pos < 0) { - return Qnil; + return pos; } } @@ -1854,8 +1854,5 @@ rb_reg_match_pos(VALUE re, VALUE str, lo } pos = rb_reg_search(re, str, pos, 0); - if (pos < 0) { - return Qnil; - } - return LONG2FIX(pos); + return pos; } @@ -1872,5 +1869,7 @@ VALUE rb_reg_match(VALUE re, VALUE str) { - return rb_reg_match_pos(re, str, 0); + long pos = rb_reg_match_pos(re, str, 0); + if (pos < 0) return Qnil; + return LONG2FIX(pos); } @@ -1937,4 +1936,5 @@ rb_reg_match2(VALUE re) return Qnil; } + start = rb_str_sublen(line, start); return LONG2FIX(start); } @@ -1982,6 +1982,6 @@ rb_reg_match_m(int argc, VALUE *argv, VA } - result = rb_reg_match_pos(re, str, pos); - if (NIL_P(result)) { + pos = rb_reg_match_pos(re, str, pos); + if (pos < 0) { rb_backref_set(Qnil); return Qnil; -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦