summaryrefslogtreecommitdiff
path: root/test/ruby/test_io_buffer.rb
diff options
context:
space:
mode:
authorKasumi Hanazuki <[email protected]>2024-11-07 05:55:39 +0900
committerGitHub <[email protected]>2024-11-06 20:55:39 +0000
commit35bf6603372360c7680653328274a670fa1d9f38 (patch)
treef6982777da87e3f404b8d45478e80bef97dba3cf /test/ruby/test_io_buffer.rb
parent56ecc243e230e8e99761ec0ffc5116601f094bb0 (diff)
io_buffer.c: Allow copies between overlapping buffers with #copy and #set_string (#11640)
The current implementation of `IO::Buffer#copy` and `#set_string` has an undefined behavior when the source and destination memory overlaps, due to the underlying use of the `memcpy` C function. This patch guarantees the methods to be safe even when copying between overlapping buffers by replacing `memcpy` with `memmove`, Fixes: [Bug #20745]
Notes
Notes: Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'test/ruby/test_io_buffer.rb')
-rw-r--r--test/ruby/test_io_buffer.rb50
1 files changed, 50 insertions, 0 deletions
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 178ed05003..55296c1f23 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -633,4 +633,54 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
end
+
+ def test_copy_overlapped_fwd
+ buf = IO::Buffer.for('0123456789').dup
+ buf.copy(buf, 3, 7)
+ assert_equal '0120123456', buf.get_string
+ end
+
+ def test_copy_overlapped_bwd
+ buf = IO::Buffer.for('0123456789').dup
+ buf.copy(buf, 0, 7, 3)
+ assert_equal '3456789789', buf.get_string
+ end
+
+ def test_copy_null_destination
+ buf = IO::Buffer.new(0)
+ assert_predicate buf, :null?
+ buf.copy(IO::Buffer.for('a'), 0, 0)
+ assert_predicate buf, :empty?
+ end
+
+ def test_copy_null_source
+ buf = IO::Buffer.for('a').dup
+ src = IO::Buffer.new(0)
+ assert_predicate src, :null?
+ buf.copy(src, 0, 0)
+ assert_equal 'a', buf.get_string
+ end
+
+ def test_set_string_overlapped_fwd
+ str = +'0123456789'
+ IO::Buffer.for(str) do |buf|
+ buf.set_string(str, 3, 7)
+ end
+ assert_equal '0120123456', str
+ end
+
+ def test_set_string_overlapped_bwd
+ str = +'0123456789'
+ IO::Buffer.for(str) do |buf|
+ buf.set_string(str, 0, 7, 3)
+ end
+ assert_equal '3456789789', str
+ end
+
+ def test_set_string_null_destination
+ buf = IO::Buffer.new(0)
+ assert_predicate buf, :null?
+ buf.set_string('a', 0, 0)
+ assert_predicate buf, :empty?
+ end
end