Bug #22195
openIO::Buffer read after free silently returns empty data instead of raising
Description
Reading from an IO::Buffer after calling #free does not raise. It behaves like an empty buffer:
Why this looks like an unintended regression¶
Originally (https://github.com/ruby/ruby/commit/e30920354f, Ruby 3.1–3.3), accessing a freed buffer raised IO::Buffer::AllocationError ("The buffer is not allocated!").
https://github.com/ruby/ruby/commit/c5cf4d4e12 made zero-length buffer operations succeed instead of raising, for [Bug #19542] and [Bug #18805]. Since a freed buffer also has base == NULL, size == 0, it was caught in the same code path and stopped raising too. Neither ticket mentions freed buffers, so this appears to be an accidental side effect rather than a decision.
Note that the rdoc of #free still promises that access after free raises.
Proposal¶
How about marking a buffer internally as freed when its memory is released, so that:
- Any byte access raises
IO::Buffer::AllocationErroragain, restoring the pre-3.4 documented behavior. #resizere-allocates and clears the mark, as#free's rdoc promises ("You can resize a freed buffer to re-allocate it").- The zero-length buffer semantics from https://github.com/ruby/ruby/pull/9532 are preserved.