diff --git a/ChangeLog b/ChangeLog index b8291dc4cf..80406bf540 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sat Aug 20 10:43:24 2011 Nobuyoshi Nakada + + * ext/stringio/stringio.c (strio_read): return new string if nil + is explicitly given as a buffer ([Bug #5207]), otherwise set the + encoding. also removed dead code. + Fri Aug 19 14:25:51 2011 Nobuyoshi Nakada * process.c (proc_spawn_v, proc_spawn): should not wait the diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 68baf350f5..5aa2d27ef3 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -1219,12 +1219,15 @@ strio_read(int argc, VALUE *argv, VALUE self) struct StringIO *ptr = readable(StringIO(self)); VALUE str = Qnil; long len; + int binary = 0; switch (argc) { case 2: str = argv[1]; - StringValue(str); - rb_str_modify(str); + if (!NIL_P(str)) { + StringValue(str); + rb_str_modify(str); + } case 1: if (!NIL_P(argv[0])) { len = NUM2LONG(argv[0]); @@ -1235,6 +1238,7 @@ strio_read(int argc, VALUE *argv, VALUE self) if (!NIL_P(str)) rb_str_resize(str, 0); return Qnil; } + binary = 1; break; } /* fall through */ @@ -1258,21 +1262,19 @@ strio_read(int argc, VALUE *argv, VALUE self) } if (NIL_P(str)) { str = strio_substr(ptr, ptr->pos, len); - if (argc > 0) rb_enc_associate(str, rb_ascii8bit_encoding()); + if (binary) rb_enc_associate(str, rb_ascii8bit_encoding()); } else { long rest = RSTRING_LEN(ptr->string) - ptr->pos; if (len > rest) len = rest; rb_str_resize(str, len); MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len); + if (binary) + rb_enc_associate(str, rb_ascii8bit_encoding()); + else + rb_enc_copy(str, ptr->string); } - if (NIL_P(str)) { - str = rb_str_new(0, 0); - len = 0; - } - else { - ptr->pos += len = RSTRING_LEN(str); - } + ptr->pos += RSTRING_LEN(str); return str; } diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb index 0258218755..26fcc624e2 100644 --- a/test/stringio/test_stringio.rb +++ b/test/stringio/test_stringio.rb @@ -418,6 +418,14 @@ class TestStringIO < Test::Unit::TestCase assert_equal("\u3042\u3044", f.read) f.rewind assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT), f.read(f.size)) + + bug5207 = '[ruby-core:39026]' + f.rewind + assert_equal("\u3042\u3044", f.read(nil, nil), bug5207) + f.rewind + s = "" + f.read(nil, s) + assert_equal("\u3042\u3044", s, bug5207) end def test_readpartial