Skip to content

Commit 073172d

Browse files
strio_read: preserve buffer encoding on partial reads (#95)
[[Bug #20418]](https://bugs.ruby-lang.org/issues/20418) Ruby IO#read preserves the encoding on partial read, but change it when reading the whole IO from commit ruby/ruby@0ca7036: > * io.c (read_all): should associate default external encoding. > * io.c (io_read): should NOT associate default external encoding. Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
1 parent 0da5b72 commit 073172d

2 files changed

Lines changed: 18 additions & 7 deletions

File tree

‎ext/stringio/stringio.c‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,10 +1623,9 @@ strio_read(int argc, VALUE *argv, VALUE self)
16231623
if (len>rest) len=rest;
16241624
rb_str_resize(str, len);
16251625
MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) +ptr->pos, char, len);
1626-
if (binary)
1627-
rb_enc_associate(str, rb_ascii8bit_encoding());
1628-
else
1626+
if (!binary) {
16291627
rb_enc_copy(str, ptr->string);
1628+
}
16301629
}
16311630
ptr->pos+=RSTRING_LEN(str);
16321631
returnstr;

‎test/stringio/test_stringio.rb‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,18 @@ def test_read
700700
s.force_encoding(Encoding::US_ASCII)
701701
assert_same(s,f.read(nil,s))
702702
assert_string("",Encoding::UTF_8,s,bug13806)
703+
704+
bug20418='[Bug #20418] ™€®'.b
705+
f=StringIO.new(bug20418)
706+
s=""
707+
assert_equal(Encoding::UTF_8,s.encoding,bug20418)
708+
f.read(4,s)
709+
assert_equal(Encoding::UTF_8,s.encoding,bug20418)
710+
711+
f.rewind
712+
s=""
713+
f.read(nil,s)
714+
assert_equal(Encoding::ASCII_8BIT,s.encoding,bug20418)
703715
end
704716

705717
deftest_readpartial
@@ -711,8 +723,8 @@ def test_readpartial
711723
assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT),f.readpartial(f.size))
712724
f.rewind
713725
# not empty buffer
714-
s='0123456789'
715-
assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT),f.readpartial(f.size,s))
726+
s='0123456789'.b
727+
assert_equal("\u3042\u3044".b,f.readpartial(f.size,s))
716728
end
717729

718730
deftest_read_nonblock
@@ -736,8 +748,8 @@ def test_read_nonblock_no_exceptions
736748
assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT),f.read_nonblock(f.size))
737749
f.rewind
738750
# not empty buffer
739-
s='0123456789'
740-
assert_equal("\u3042\u3044".force_encoding(Encoding::ASCII_8BIT),f.read_nonblock(f.size,s))
751+
s='0123456789'.b
752+
assert_equal("\u3042\u3044".b,f.read_nonblock(f.size,s))
741753
end
742754

743755
deftest_sysread

0 commit comments

Comments
 (0)