Skip to content

Commit 3d90045

Browse files
committed
Add regression test for byte-pool bug breaking ensure_capacity()
1 parent 1963ced commit 3d90045

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/imap_stream.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ impl Buffer {
201201
let increase = std::cmp::max(Buffer::BLOCK_SIZE, extra_bytes_needed);
202202
self.grow(increase)?;
203203
}
204+
205+
// Assert that the buffer at least one free byte.
206+
debug_assert!(self.offset < self.block.size());
204207
Ok(())
205208
}
206209

@@ -402,6 +405,35 @@ mod tests {
402405
assert_eq!(buf.block.size(), 3 * Buffer::BLOCK_SIZE);
403406
}
404407

408+
/// Regression test for a bug in ensure_capacity() caused
409+
/// by a bug in byte-pool crate 0.2.2 dependency.
410+
///
411+
/// ensure_capacity() sometimes did not ensure that
412+
/// at least one byte is available, which in turn
413+
/// resulted in attempt to read into a buffer of zero size.
414+
/// When poll_read() reads into a buffer of zero size,
415+
/// it can only read zero bytes, which is indistinguishable
416+
/// from EOF and resulted in an erroneous detection of EOF
417+
/// when in fact the stream was not closed.
418+
#[test]
419+
fn test_ensure_capacity_loop() {
420+
let mut buf = Buffer::new();
421+
422+
for i in 1..500 {
423+
// Ask for `i` bytes.
424+
buf.ensure_capacity(i).unwrap();
425+
426+
// Test that we can read at least as much as requested.
427+
let free = buf.free_as_mut_slice();
428+
let used = free.len();
429+
assert!(used >= i);
430+
drop(free);
431+
432+
// Use as much as allowed.
433+
buf.extend_used(used);
434+
}
435+
}
436+
405437
#[test]
406438
fn test_buffer_take_and_return_block() {
407439
// This test identifies blocks by their size.

0 commit comments

Comments
 (0)