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) {
|
while (1) {
|
||||||
long numwrote;
|
long numwrote;
|
||||||
long l;
|
long l;
|
||||||
|
rb_str_make_independent(buf);
|
||||||
if (stp->copy_length < (rb_off_t)0) {
|
if (stp->copy_length < (rb_off_t)0) {
|
||||||
l = buflen;
|
l = buflen;
|
||||||
}
|
}
|
||||||
|
@ -1141,6 +1141,34 @@ class TestIO < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
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
|
def test_copy_stream_write_in_binmode
|
||||||
bug8767 = '[ruby-core:56518] [Bug #8767]'
|
bug8767 = '[ruby-core:56518] [Bug #8767]'
|
||||||
mkcdtmpdir {
|
mkcdtmpdir {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user