diff options
| author | Andrii Furmanets <furmanets.andriy@gmail.com> | 2026-05-13 11:29:30 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-13 17:29:30 +0900 |
| commit | f3dd724da56ce61024781c6868577aaa79218412 (patch) | |
| tree | c7445e126270276c2420b73d60c51d3141636d3c | |
| parent | fc5f23f8d02bd3d685292706973117dfd99c0ebe (diff) | |
Fix `IO::Buffer#each_byte` bounds check. (#16823)
| -rw-r--r-- | io_buffer.c | 4 | ||||
| -rw-r--r-- | test/ruby/test_io_buffer.rb | 8 |
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) |
