summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <[email protected]>2025-03-16 20:10:00 +0900
committernagachika <[email protected]>2025-03-16 20:35:27 +0900
commitf85e5e01bafeca387e833b9d79cab43a8b22aa3d (patch)
treea26f003a3429f51036b052d78d352a301c7b95fc
parent2b2ab1a67c236eb0c47e63e8adcf877b0d20a38c (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.c1
-rw-r--r--test/ruby/test_io.rb28
-rw-r--r--version.h2
3 files changed, 30 insertions, 1 deletions
diff --git a/io.c b/io.c
index 17f8d5799a..7f23656049 100644
--- a/io.c
+++ b/io.c
@@ -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 {
diff --git a/version.h b/version.h
index 4b21ab9908..63f382a26d 100644
--- a/version.h
+++ b/version.h
@@ -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"