Skip to content

Commit

Permalink
Fix StringIO#initialize and preserve initial string's encoding when m…
Browse files Browse the repository at this point in the history
…ode is `w` so the initial string is truncated

* close #3599
  • Loading branch information
andrykonchin committed Jun 28, 2024
1 parent 954bfcf commit 740eddb
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Compatibility:
* Fix `Enumerable#reduce` to handle non-Symbol method name parameter (#2931, @andrykonchin).
* Fix `RangeError` message to match CRuby for `Integer#chr` called with invalid codepoint argument (#2795, @andrykonchin).
* Joni has been updated from 2.1.44 to 2.2.1 (@andrykonchin).
* Fix `StringIO#initialize` and preserve initial string's encoding when mode is `w` so the initial string is truncated (#3599, @andrykonchin).

Performance:

Expand Down
4 changes: 2 additions & 2 deletions lib/truffle/stringio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ def yaml_initialize(type, val)

d = @__data__ # no sync, only called from initialize
raise Errno::EACCES, 'Permission denied' if @writable && d.string.frozen?
d.string.replace('') if truncate
d.string.replace(''.force_encoding(d.string.encoding)) if truncate
end

private def mode_from_integer(mode)
Expand All @@ -708,7 +708,7 @@ def yaml_initialize(type, val)
end

@append = true if (mode & IO::APPEND) != 0
d.string.replace('') if (mode & IO::TRUNC) != 0
d.string.replace(''.force_encoding(d.string.encoding)) if (mode & IO::TRUNC) != 0
end

private def getline(arg_error, sep, limit, chomp = false)
Expand Down
20 changes: 20 additions & 0 deletions spec/ruby/library/stringio/initialize_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,26 @@
-> { @io.send(:initialize, str, "w") }.should raise_error(Errno::EACCES)
-> { @io.send(:initialize, str, "a") }.should raise_error(Errno::EACCES)
end

it "truncates all the content if passed w mode" do
io = StringIO.allocate
source = +"example".encode(Encoding::ISO_8859_1);

io.send(:initialize, source, "w")

io.string.should.empty?
io.string.encoding.should == Encoding::ISO_8859_1
end

it "truncates all the content if passed IO::TRUNC mode" do
io = StringIO.allocate
source = +"example".encode(Encoding::ISO_8859_1);

io.send(:initialize, source, IO::TRUNC)

io.string.should.empty?
io.string.encoding.should == Encoding::ISO_8859_1
end
end

describe "StringIO#initialize when passed [Object]" do
Expand Down

0 comments on commit 740eddb

Please sign in to comment.