From c13757ed9ae02a2d03aea91bb852397aa920f3fd Mon Sep 17 00:00:00 2001 From: nagachika Date: Sun, 16 Jul 2023 16:42:12 +0900 Subject: [PATCH] merge revision(s) 09295ea796900fb7b05d29e93364090e21598566: [Backport #19543] 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. --- io_buffer.c | 5 +++++ test/ruby/test_io_buffer.rb | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) --- io_buffer.c | 5 +++++ test/ruby/test_io_buffer.rb | 18 ++++++++++++++++++ version.h | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/io_buffer.c b/io_buffer.c index 6a6bc25628..1fa6473328 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -1391,6 +1391,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 d9fa22fd2a..45813256e4 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -142,6 +142,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 diff --git a/version.h b/version.h index cd1bdf5394..639f98d7c4 100644 --- a/version.h +++ b/version.h @@ -11,7 +11,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 2 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 68 +#define RUBY_PATCHLEVEL 69 #include "ruby/version.h" #include "ruby/internal/abi.h"