Skip to content

Commit 3986992

Browse files
committed
fix: StringIO#write transcodes strings with a different encoding
1 parent dd4e885 commit 3986992

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Bug fixes:
2424
* Fix constants lookup when `BasicObject#instance_eval` method is called with a String (#2810, @andrykonchin).
2525
* Don't trigger the `method_added` event when changing a method's visibility or calling `module_function` (@paracycle, @nirvdrum).
2626
* Fix `rb_time_timespec_new` function to not call `Time.at` method directly (@andrykonchin).
27+
* Fix `StringIO#write` to transcode strings with encodings that don't match the `StringIO`'s `external_encoding`. (#2839, @flavorjones)
2728

2829
Compatibility:
2930

lib/truffle/stringio.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,13 @@ def write(str)
280280
str = String(str)
281281
return 0 if str.empty?
282282

283+
if external_encoding &&
284+
external_encoding != str.encoding &&
285+
external_encoding != Encoding::BINARY &&
286+
str.encoding != Encoding::BINARY
287+
str = str.encode(external_encoding)
288+
end
289+
283290
d = @__data__
284291
TruffleRuby.synchronized(d) do
285292
pos = d.pos

spec/ruby/library/stringio/write_spec.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,23 @@
1717
describe "StringIO#write when in append mode" do
1818
it_behaves_like :stringio_write_append, :write
1919
end
20+
21+
describe "StringIO#write transcoding" do
22+
describe "when UTF-16 encoding is set" do
23+
it "accepts a UTF-8-encoded string and transcodes it" do
24+
io = StringIO.new.set_encoding(Encoding::UTF_16)
25+
utf8_str = "hello"
26+
27+
io.write(utf8_str)
28+
29+
result = io.string
30+
expected = [
31+
254, 255, # BOM
32+
0, 104, 0, 101, 0, 108, 0, 108, 0, 111, # double-width "hello"
33+
]
34+
35+
io.external_encoding.should == Encoding::UTF_16
36+
result.bytes.should == expected
37+
end
38+
end
39+
end

0 commit comments

Comments
 (0)