Skip to content

Commit 073172d

Browse files
casperisfinebyroot
andauthored
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 <[email protected]>
1 parent 0da5b72 commit 073172d

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

ext/stringio/stringio.c

+2-3
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
return str;

test/stringio/test_stringio.rb

+16-4
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
def test_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
def test_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
def test_sysread

0 commit comments

Comments
 (0)