diff options
author | nagachika <[email protected]> | 2025-03-16 20:10:00 +0900 |
---|---|---|
committer | nagachika <[email protected]> | 2025-03-16 20:35:27 +0900 |
commit | f85e5e01bafeca387e833b9d79cab43a8b22aa3d (patch) | |
tree | a26f003a3429f51036b052d78d352a301c7b95fc | |
parent | 2b2ab1a67c236eb0c47e63e8adcf877b0d20a38c (diff) |
merge revision(s) f423f6e10c0c226dfed98e7cb7a5d489191dfa35: [Backport #21131]
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]
-rw-r--r-- | io.c | 1 | ||||
-rw-r--r-- | test/ruby/test_io.rb | 28 | ||||
-rw-r--r-- | version.h | 2 |
3 files changed, 30 insertions, 1 deletions
@@ -13098,6 +13098,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; } diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 51c9f2b83c..16de2e8a76 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -1116,6 +1116,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{|cls| payload << cls}) + 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 { @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 7 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 134 +#define RUBY_PATCHLEVEL 135 #include "ruby/version.h" #include "ruby/internal/abi.h" |