diff --git a/tokio/src/io/async_read.rs b/tokio/src/io/async_read.rs index d28280a51..24c1b4efb 100644 --- a/tokio/src/io/async_read.rs +++ b/tokio/src/io/async_read.rs @@ -123,7 +123,9 @@ pub trait AsyncRead { // Convert to `&mut [u8]` let b = &mut *(b as *mut [MaybeUninit] as *mut [u8]); - ready!(self.poll_read(cx, b))? + let n = ready!(self.poll_read(cx, b))?; + assert!(n <= b.len(), "Bad AsyncRead implementation, more bytes were reported as read than the buffer can hold"); + n }; buf.advance_mut(n); diff --git a/tokio/tests/io_read.rs b/tokio/tests/io_read.rs index d18615e45..4791c9a66 100644 --- a/tokio/tests/io_read.rs +++ b/tokio/tests/io_read.rs @@ -36,3 +36,25 @@ async fn read() { assert_eq!(n, 11); assert_eq!(buf[..], b"hello world"[..]); } + +struct BadAsyncRead; + +impl AsyncRead for BadAsyncRead { + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + for b in &mut *buf { + *b = b'a'; + } + Poll::Ready(Ok(buf.len() * 2)) + } +} + +#[tokio::test] +#[should_panic] +async fn read_buf_bad_async_read() { + let mut buf = Vec::with_capacity(10); + BadAsyncRead.read_buf(&mut buf).await.unwrap(); +}