Ensure IO.copy_stream buffer is an independent string
Otherwise, changes to the buffer by the destination write method could result in data changing for supposedly independent strings. Fixes [Bug #21131]
This commit is contained in:
parent
6e510d78c0
commit
f423f6e10c
Notes:
git
2025-02-19 01:18:32 +00:00
1
io.c
1
io.c
@ -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;
|
||||
}
|
||||
|
@ -1141,6 +1141,34 @@ class TestIO < Test::Unit::TestCase
|
||||
}
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user