Do not change IO.pipe encodings if encodings explicitly given

This commit makes it so that if the binmode option is given with
any encoding arguments, the reader and writer IO objects are
not set to binary encoding.

Fixes [Bug #12989]
This commit is contained in:
Jeremy Evans 2019-07-25 13:47:08 -07:00
parent d8562ab2a4
commit ebc99e026d
2 changed files with 40 additions and 24 deletions

2
io.c
View File

@ -10313,7 +10313,7 @@ rb_io_s_pipe(int argc, VALUE *argv, VALUE klass)
extract_binmode(opt, &fmode);
if (fmode & FMODE_BINMODE) {
if ((fmode & FMODE_BINMODE) && v1 == Qnil) {
rb_io_ascii8bit_binmode(r);
rb_io_ascii8bit_binmode(w);
}

View File

@ -113,35 +113,51 @@ class TestIO < Test::Unit::TestCase
].each{|thr| thr.join}
end
def test_binmode_writer
def test_binmode_pipe
EnvUtil.with_default_internal(Encoding::UTF_8) do
reader, writer = IO.pipe
reader.binmode
writer.binmode
EnvUtil.with_default_external(Encoding::UTF_8) do
reader, writer = IO.pipe
reader.binmode
writer.binmode
reader2, writer2 = IO.pipe(binmode: true)
reader1, writer1 = IO.pipe
assert writer.binmode?
assert writer2.binmode?
assert_equal writer.binmode?, writer2.binmode?
assert_equal writer.external_encoding, writer2.external_encoding
assert_equal writer.internal_encoding, writer2.internal_encoding
end
end
reader2, writer2 = IO.pipe(binmode: true)
assert_predicate writer, :binmode?
assert_predicate writer2, :binmode?
assert_equal writer.binmode?, writer2.binmode?
assert_equal writer.external_encoding, writer2.external_encoding
assert_equal writer.internal_encoding, writer2.internal_encoding
assert_predicate reader, :binmode?
assert_predicate reader2, :binmode?
assert_equal reader.binmode?, reader2.binmode?
assert_equal reader.external_encoding, reader2.external_encoding
assert_equal reader.internal_encoding, reader2.internal_encoding
def test_binmode_reader
EnvUtil.with_default_internal(Encoding::UTF_8) do
reader, writer = IO.pipe
reader.binmode
writer.binmode
reader3, writer3 = IO.pipe("UTF-8:UTF-8", binmode: true)
assert_predicate writer3, :binmode?
assert_equal writer1.external_encoding, writer3.external_encoding
assert_equal writer1.internal_encoding, writer3.internal_encoding
assert_predicate reader3, :binmode?
assert_equal reader1.external_encoding, reader3.external_encoding
assert_equal reader1.internal_encoding, reader3.internal_encoding
reader2, writer2 = IO.pipe(binmode: true)
reader4, writer4 = IO.pipe("UTF-8:UTF-8", binmode: true)
assert_predicate writer4, :binmode?
assert_equal writer1.external_encoding, writer4.external_encoding
assert_equal writer1.internal_encoding, writer4.internal_encoding
assert_predicate reader4, :binmode?
assert_equal reader1.external_encoding, reader4.external_encoding
assert_equal reader1.internal_encoding, reader4.internal_encoding
assert reader.binmode?
assert reader2.binmode?
assert_equal reader.binmode?, reader2.binmode?
assert_equal reader.external_encoding, reader2.external_encoding
assert_equal reader.internal_encoding, reader2.internal_encoding
reader5, writer5 = IO.pipe("UTF-8", "UTF-8", binmode: true)
assert_predicate writer5, :binmode?
assert_equal writer1.external_encoding, writer5.external_encoding
assert_equal writer1.internal_encoding, writer5.internal_encoding
assert_predicate reader5, :binmode?
assert_equal reader1.external_encoding, reader5.external_encoding
assert_equal reader1.internal_encoding, reader5.internal_encoding
end
end
end