summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrii Furmanets <furmanets.andriy@gmail.com>2026-05-13 11:29:30 +0300
committerGitHub <noreply@github.com>2026-05-13 17:29:30 +0900
commitf3dd724da56ce61024781c6868577aaa79218412 (patch)
treec7445e126270276c2420b73d60c51d3141636d3c
parentfc5f23f8d02bd3d685292706973117dfd99c0ebe (diff)
Fix `IO::Buffer#each_byte` bounds check. (#16823)
-rw-r--r--io_buffer.c4
-rw-r--r--test/ruby/test_io_buffer.rb8
2 files changed, 12 insertions, 0 deletions
diff --git a/io_buffer.c b/io_buffer.c
index 89483a23f2..6dbc824e59 100644
--- a/io_buffer.c
+++ b/io_buffer.c
@@ -2334,6 +2334,10 @@ io_buffer_each_byte(int argc, VALUE *argv, VALUE self)
size_t offset, count;
io_buffer_extract_offset_count(RB_IO_BUFFER_DATA_TYPE_U8, size, argc, argv, &offset, &count);
+ if (size_sum_is_bigger_than(offset, count, size)) {
+ rb_raise(rb_eArgError, "Specified offset+count is bigger than the buffer size!");
+ }
+
for (size_t i = 0; i < count; i++) {
unsigned char *value = (unsigned char *)base + i + offset;
rb_yield(RB_INT2FIX(*value));
diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 5662f0daf9..6213bb28d7 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -494,6 +494,14 @@ class TestIOBuffer < Test::Unit::TestCase
assert_equal string.bytes[3, 5], buffer.each_byte(3, 5).to_a
end
+ def test_each_byte_bounds_error
+ buffer = IO::Buffer.for("A")
+
+ assert_raise(ArgumentError) { buffer.each_byte(0, 2).to_a }
+ assert_raise(ArgumentError) { buffer.each_byte(1, 1).to_a }
+ assert_raise(ArgumentError) { buffer.each_byte(SIZE_MAX, 0).to_a }
+ end
+
def test_zero_length_each_byte
buffer = IO::Buffer.new(0)