Skip to content

Commit 211daff

Browse files
Zettrokelelongg
authored andcommitted
Fix chain remaining_mut(), allowing to chain growing buffer (tokio-rs#488)
1 parent a1e804d commit 211daff

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
@@ -57,6 +57,10 @@ pub unsafe trait BufMut {
5757
/// Implementations of `remaining_mut` should ensure that the return value
5858
/// does not change unless a call is made to `advance_mut` or any other
5959
/// function that is documented to change the `BufMut`'s current position.
60+
///
61+
/// # Note
62+
///
63+
/// `remaining_mut` may return value smaller than actual available space.
6064
fn remaining_mut(&self) -> usize;
6165

6266
/// 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
@@ -139,6 +139,28 @@ fn vectored_read() {
139139
}
140140
}
141141

142+
#[test]
143+
fn chain_growing_buffer() {
144+
let mut buff = [' ' as u8; 10];
145+
let mut vec = b"wassup".to_vec();
146+
147+
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
148+
149+
chained.put_slice(b"hey there123123");
150+
151+
assert_eq!(&buff, b"hey there1");
152+
assert_eq!(&vec, b"wassup23123");
153+
}
154+
155+
#[test]
156+
fn chain_overflow_remaining_mut() {
157+
let mut chained = Vec::<u8>::new().chain_mut(Vec::new()).chain_mut(Vec::new());
158+
159+
assert_eq!(chained.remaining_mut(), usize::MAX);
160+
chained.put_slice(&[0; 256]);
161+
assert_eq!(chained.remaining_mut(), usize::MAX);
162+
}
163+
142164
#[test]
143165
fn chain_get_bytes() {
144166
let mut ab = Bytes::copy_from_slice(b"ab");

0 commit comments

Comments
 (0)