Skip to content
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

Merged
merged 2 commits into from Mar 24, 2023

Conversation

hanazuki
Copy link
Contributor

Fixes: https://bugs.ruby-lang.org/issues/19543

#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 frees the memory when the new size is zero.

`#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.
Copy link
Member

@kou kou left a 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?

Copy link
Member

@ioquatix ioquatix left a 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):

  1. Raise error.
  2. Free buffer.
  3. 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 ioquatix merged commit 09295ea into ruby:master Mar 24, 2023
93 of 96 checks passed
@hanazuki
Copy link
Contributor Author

@ioquatix Thanks for your review. Your addition to the test makes sense.

@hanazuki hanazuki deleted the io-buffer-resize-0 branch March 25, 2023 07:01
matzbot pushed a commit that referenced this pull request Jul 16, 2023
	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(+)
matzbot pushed a commit that referenced this pull request Jul 25, 2023
	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(+)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants