From f3dd724da56ce61024781c6868577aaa79218412 Mon Sep 17 00:00:00 2001 From: Andrii Furmanets Date: Wed, 13 May 2026 11:29:30 +0300 Subject: Fix `IO::Buffer#each_byte` bounds check. (#16823) --- io_buffer.c | 4 ++++ test/ruby/test_io_buffer.rb | 8 ++++++++ 2 files changed, 12 insertions(+) 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) -- cgit v1.2.3