Skip to content

Commit c5cf4d4

Browse files
authored
Improve behavioural consistency of unallocated (zero length) IO::Buffer. (ruby#9532)
This makes the behaviour of IO::Buffer.new(0) and IO::Buffer.new.slice(0, 0) consistent. Fixes https://bugs.ruby-lang.org/issues/19542 and https://bugs.ruby-lang.org/issues/18805.
1 parent 5c823aa commit c5cf4d4

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

io_buffer.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -854,11 +854,10 @@ io_buffer_get_bytes_for_writing(struct rb_io_buffer *buffer, void **base, size_t
854854
if (buffer->base) {
855855
*base = buffer->base;
856856
*size = buffer->size;
857-
858-
return;
857+
} else {
858+
*base = NULL;
859+
*size = 0;
859860
}
860-
861-
rb_raise(rb_eIOBufferAllocationError, "The buffer is not allocated!");
862861
}
863862

864863
void
@@ -880,11 +879,10 @@ io_buffer_get_bytes_for_reading(struct rb_io_buffer *buffer, const void **base,
880879
if (buffer->base) {
881880
*base = buffer->base;
882881
*size = buffer->size;
883-
884-
return;
882+
} else {
883+
*base = NULL;
884+
*size = 0;
885885
}
886-
887-
rb_raise(rb_eIOBufferAllocationError, "The buffer is not allocated!");
888886
}
889887

890888
void

test/ruby/test_io_buffer.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,14 @@ def test_compare_different_size
199199
assert_positive buffer2 <=> buffer1
200200
end
201201

202+
def test_compare_zero_length
203+
buffer1 = IO::Buffer.new(0)
204+
buffer2 = IO::Buffer.new(1)
205+
206+
assert_negative buffer1 <=> buffer2
207+
assert_positive buffer2 <=> buffer1
208+
end
209+
202210
def test_slice
203211
buffer = IO::Buffer.new(128)
204212
slice = buffer.slice(8, 32)
@@ -270,6 +278,14 @@ def test_get_string
270278
end
271279
end
272280

281+
def test_zero_length_get_string
282+
buffer = IO::Buffer.new.slice(0, 0)
283+
assert_equal "", buffer.get_string
284+
285+
buffer = IO::Buffer.new(0)
286+
assert_equal "", buffer.get_string
287+
end
288+
273289
# We check that values are correctly round tripped.
274290
RANGES = {
275291
:U8 => [0, 2**8-1],
@@ -316,6 +332,13 @@ def test_get_set_values
316332
end
317333
end
318334

335+
def test_zero_length_get_set_values
336+
buffer = IO::Buffer.new(0)
337+
338+
assert_equal [], buffer.get_values([], 0)
339+
assert_equal 0, buffer.set_values([], 0, [])
340+
end
341+
319342
def test_values
320343
buffer = IO::Buffer.new(128)
321344

@@ -340,13 +363,25 @@ def test_each
340363
end
341364
end
342365

366+
def test_zero_length_each
367+
buffer = IO::Buffer.new(0)
368+
369+
assert_equal [], buffer.each(:U8).to_a
370+
end
371+
343372
def test_each_byte
344373
string = "The quick brown fox jumped over the lazy dog."
345374
buffer = IO::Buffer.for(string)
346375

347376
assert_equal string.bytes, buffer.each_byte.to_a
348377
end
349378

379+
def test_zero_length_each_byte
380+
buffer = IO::Buffer.new(0)
381+
382+
assert_equal [], buffer.each_byte.to_a
383+
end
384+
350385
def test_clear
351386
buffer = IO::Buffer.new(16)
352387
buffer.set_string("Hello World!")

0 commit comments

Comments
 (0)