Fix missing handling of offset argument in IO::Buffer pread and pwrite. (#7012)

This commit is contained in:
Samuel Williams 2022-12-23 10:52:10 -08:00 committed by GitHub
parent af4cd997a1
commit 11ad9a42d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2022-12-23 18:52:32 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
2 changed files with 47 additions and 4 deletions

View File

@ -1093,6 +1093,8 @@ rb_io_buffer_free(VALUE self)
return self;
}
// Validate that access to the buffer is within bounds, assuming you want to
// access length bytes from the specified offset.
static inline void
io_buffer_validate_range(struct rb_io_buffer *data, size_t offset, size_t length)
{
@ -2510,7 +2512,7 @@ rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t of
struct rb_io_buffer *data = NULL;
TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, data);
io_buffer_validate_range(data, 0, length);
io_buffer_validate_range(data, offset, length);
int descriptor = rb_io_descriptor(io);
@ -2520,8 +2522,14 @@ rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t of
struct io_buffer_pread_internal_argument argument = {
.descriptor = descriptor,
.base = base,
// Move the base pointer to the offset:
.base = (unsigned char*)base + offset,
// And the size to the length of data we want to read:
.size = length,
// From the offset in the file we want to read from:
.offset = from,
};
@ -2677,7 +2685,7 @@ rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t o
struct rb_io_buffer *data = NULL;
TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, data);
io_buffer_validate_range(data, 0, length);
io_buffer_validate_range(data, offset, length);
int descriptor = rb_io_descriptor(io);
@ -2687,8 +2695,14 @@ rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t o
struct io_buffer_pwrite_internal_argument argument = {
.descriptor = descriptor,
.base = base,
// Move the base pointer to the offset:
.base = (unsigned char *)base + offset,
// And the size to the length of data we want to read:
.size = length,
// And the offset in the file we want to write from:
.offset = from,
};

View File

@ -373,6 +373,20 @@ class TestIOBuffer < Test::Unit::TestCase
io.close!
end
def test_pread_offset
io = Tempfile.new
io.write("Hello World")
io.seek(0)
buffer = IO::Buffer.new(128)
buffer.pread(io, 6, 5, 6)
assert_equal "World", buffer.get_string(6, 5)
assert_equal 0, io.tell
ensure
io.close!
end
def test_pwrite
io = Tempfile.new
@ -388,6 +402,21 @@ class TestIOBuffer < Test::Unit::TestCase
io.close!
end
def test_pwrite_offset
io = Tempfile.new
buffer = IO::Buffer.new(128)
buffer.set_string("Hello World")
buffer.pwrite(io, 6, 5, 6)
assert_equal 0, io.tell
io.seek(6)
assert_equal "World", io.read(5)
ensure
io.close!
end
def test_operators
source = IO::Buffer.for("1234123412")
mask = IO::Buffer.for("133\x00")