Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unsafe impl<'a> BufMut for ReadBuf<'a> #5590

Merged
merged 19 commits into from Apr 4, 2023
Merged
20 changes: 20 additions & 0 deletions tokio/src/io/read_buf.rs
Expand Up @@ -270,6 +270,26 @@ impl<'a> ReadBuf<'a> {
}
}

#[cfg(feature = "io-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "io-util")))]
unsafe impl<'a> bytes::BufMut for ReadBuf<'a> {
fn remaining_mut(&self) -> usize {
self.remaining()
}

unsafe fn advance_mut(&mut self, cnt: usize) {
self.advance(cnt);
}

fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
unsafe {
let len = self.unfilled_mut().len();
let ptr = self.unfilled_mut().as_mut_ptr();
bytes::buf::UninitSlice::from_raw_parts_mut(ptr as *mut u8, len)
}
amab8901 marked this conversation as resolved.
Show resolved Hide resolved
}
}

impl fmt::Debug for ReadBuf<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ReadBuf")
Expand Down
38 changes: 38 additions & 0 deletions tokio/tests/io_read_buf.rs
Expand Up @@ -34,3 +34,41 @@ async fn read_buf() {
assert_eq!(n, 11);
assert_eq!(buf[..], b"hello world"[..]);
}

#[tokio::test]
#[cfg(feature = "io-util")]
async fn issue_5588() {
use bytes::BufMut;

// steps to zero
let mut buf = [0; 8];
let mut read_buf = ReadBuf::new(&mut buf);
assert_eq!(read_buf.remaining_mut(), 8);
assert_eq!(read_buf.remaining_mut(), 8);
unsafe {
read_buf.advance_mut(1);
}
assert_eq!(read_buf.remaining_mut(), 7);
assert_eq!(read_buf.remaining_mut(), 7);
unsafe {
read_buf.advance_mut(5);
}
assert_eq!(read_buf.remaining_mut(), 2);
assert_eq!(read_buf.remaining_mut(), 2);
unsafe {
read_buf.advance_mut(2);
}
assert_eq!(read_buf.remaining_mut(), 0);
assert_eq!(read_buf.remaining_mut(), 0);

// directly to zero
let mut buf = [0; 8];
let mut read_buf = ReadBuf::new(&mut buf);
assert_eq!(read_buf.remaining_mut(), 8);
assert_eq!(read_buf.chunk_mut().len(), 8);
unsafe {
read_buf.advance_mut(8);
}
assert_eq!(read_buf.remaining_mut(), 0);
assert_eq!(read_buf.chunk_mut().len(), 0);
}