New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO::Buffer#resize: Free internal buffer if new size is zero #7569
Conversation
1cce3d2
to
8756008
Compare
`#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.
8756008
to
3894fa6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
@ioquatix Do you want to review this too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kou thanks for mentioning me so I can review.
I am okay with this change.
There are several options for resize(0)
:
- Raise error.
- Free buffer.
- Ignore.
I think that option 2 is proposed in this change, is acceptable. However, after resizing a buffer to size=0, can we resize it back to size=1? I want to add extra tests.
@ioquatix Thanks for your review. Your addition to the test makes sense. |
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#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(+)
Fixes: https://bugs.ruby-lang.org/issues/19543
#resize(0)
on an IO::Buffer with internal buffer allocated will result in callingrealloc(data->base, 0)
. The behavior ofrealloc
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.