Skip to content

Commit 3536017

Browse files
authored
Fix chain remaining_mut(), allowing to chain growing buffer (#488)
1 parent b8d27c0 commit 3536017

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

src/buf/buf_mut.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ pub unsafe trait BufMut {
5656
/// Implementations of `remaining_mut` should ensure that the return value
5757
/// does not change unless a call is made to `advance_mut` or any other
5858
/// function that is documented to change the `BufMut`'s current position.
59+
///
60+
/// # Note
61+
///
62+
/// `remaining_mut` may return value smaller than actual available space.
5963
fn remaining_mut(&self) -> usize;
6064

6165
/// Advance the internal cursor of the BufMut

src/buf/chain.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ where
198198
fn remaining_mut(&self) -> usize {
199199
self.a
200200
.remaining_mut()
201-
.checked_add(self.b.remaining_mut())
202-
.unwrap()
201+
.saturating_add(self.b.remaining_mut())
203202
}
204203

205204
fn chunk_mut(&mut self) -> &mut UninitSlice {

tests/test_chain.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,28 @@ fn vectored_read() {
133133
}
134134
}
135135

136+
#[test]
137+
fn chain_growing_buffer() {
138+
let mut buff = [' ' as u8; 10];
139+
let mut vec = b"wassup".to_vec();
140+
141+
let mut chained = (&mut buff[..]).chain_mut(&mut vec).chain_mut(Vec::new()); // Required for potential overflow because remaining_mut for Vec is isize::MAX - vec.len(), but for chain_mut is usize::MAX
142+
143+
chained.put_slice(b"hey there123123");
144+
145+
assert_eq!(&buff, b"hey there1");
146+
assert_eq!(&vec, b"wassup23123");
147+
}
148+
149+
#[test]
150+
fn chain_overflow_remaining_mut() {
151+
let mut chained = Vec::<u8>::new().chain_mut(Vec::new()).chain_mut(Vec::new());
152+
153+
assert_eq!(chained.remaining_mut(), usize::MAX);
154+
chained.put_slice(&[0; 256]);
155+
assert_eq!(chained.remaining_mut(), usize::MAX);
156+
}
157+
136158
#[test]
137159
fn chain_get_bytes() {
138160
let mut ab = Bytes::copy_from_slice(b"ab");

0 commit comments

Comments
 (0)