diff options
author | Kasumi Hanazuki <kasumi@rollingapple.net> | 2023-03-25 08:12:23 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-25 12:12:23 +1300 |
commit | 09295ea796900fb7b05d29e93364090e21598566 (patch) | |
tree | 0d590abbe67939eaaa1b9d7c79a7b31d39aa5322 | |
parent | 59c3fac6c4d803019095eebb92b0d2862450ded6 (diff) |
IO::Buffer#resize: Free internal buffer if new size is zero (#7569)
`#resize(0)` on an IO::Buffer with internal buffer allocated will
result in calling `realloc(data->base, 0)`. The behavior of `realloc`
with size = 0 is implementation-defined (glibc frees the object
and returns NULL, while BSDs return an inaccessible object). And
thus such usage is deprecated in standard C (upcoming C23 will make it
UB).
To avoid this problem, just `free`s the memory when the new size is zero.
Notes
Notes:
Merged-By: ioquatix <samuel@codeotaku.com>
-rw-r--r-- | io_buffer.c | 5 | ||||
-rw-r--r-- | test/ruby/test_io_buffer.rb | 18 |
2 files changed, 23 insertions, 0 deletions
diff --git a/io_buffer.c b/io_buffer.c index 91083cd7e4..1ff3935094 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -1422,6 +1422,11 @@ rb_io_buffer_resize(VALUE self, size_t size) #endif if (data->flags & RB_IO_BUFFER_INTERNAL) { + if (size == 0) { + io_buffer_free(data); + return; + } + void *base = realloc(data->base, size); if (!base) { diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb index 55e347471d..e29400d76e 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -156,6 +156,24 @@ class TestIOBuffer < Test::Unit::TestCase assert_equal message, buffer.get_string(0, message.bytesize) end + def test_resize_zero_internal + buffer = IO::Buffer.new(1) + + buffer.resize(0) + assert_equal 0, buffer.size + + buffer.resize(1) + assert_equal 1, buffer.size + end + + def test_resize_zero_external + buffer = IO::Buffer.for('1') + + assert_raise IO::Buffer::AccessError do + buffer.resize(0) + end + end + def test_compare_same_size buffer1 = IO::Buffer.new(1) assert_equal buffer1, buffer1 |