Skip to content

Commit

Permalink
Ensure IO.copy_stream buffer is an independent string
Browse files Browse the repository at this point in the history
Otherwise, changes to the buffer by the destination write method
could result in data changing for supposedly independent strings.

Fixes [Bug #21131]
  • Loading branch information
jeremyevans committed Feb 19, 2025
1 parent 6e510d7 commit f423f6e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
1 change: 1 addition & 0 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -13139,6 +13139,7 @@ copy_stream_fallback_body(VALUE arg)
while (1) {
long numwrote;
long l;
rb_str_make_independent(buf);
if (stp->copy_length < (rb_off_t)0) {
l = buflen;
}
Expand Down
28 changes: 28 additions & 0 deletions test/ruby/test_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,34 @@ def test_copy_stream_pathname_to_pathname
}
end

def test_copy_stream_dup_buffer
bug21131 = '[ruby-core:120961] [Bug #21131]'
mkcdtmpdir do
dst_class = Class.new do
def initialize(&block)
@block = block
end

def write(data)
@block.call(data.dup)
data.bytesize
end
end

rng = Random.new(42)
body = Tempfile.new("ruby-bug", binmode: true)
body.write(rng.bytes(16_385))
body.rewind

payload = []
IO.copy_stream(body, dst_class.new{payload << it})
body.rewind
assert_equal(body.read, payload.join, bug21131)
ensure
body&.close
end
end

def test_copy_stream_write_in_binmode
bug8767 = '[ruby-core:56518] [Bug #8767]'
mkcdtmpdir {
Expand Down

0 comments on commit f423f6e

Please sign in to comment.