Skip to content

Commit 12b0446

Browse files
committed
Add regression test for byte-pool bug breaking ensure_capacity()
1 parent 9066257 commit 12b0446

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
@@ -185,6 +185,9 @@ impl Buffer {
185185
let increase = std::cmp::max(Buffer::BLOCK_SIZE, extra_bytes_needed);
186186
self.grow(increase)?;
187187
}
188+
189+
// Assert that the buffer at least one free byte.
190+
debug_assert!(self.offset < self.block.size());
188191
Ok(())
189192
}
190193

@@ -394,6 +397,35 @@ mod tests {
394397
assert_eq!(buf.block.size(), 3 * Buffer::BLOCK_SIZE);
395398
}
396399

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

0 commit comments

Comments
 (0)