io: fix unsound pin projection in read_buf and write_buf (#2612)

This commit is contained in:
Taiki Endo
2020-06-12 14:28:23 +09:00
committed by GitHub
parent 1636910f0a
commit 1769f65d37
4 changed files with 12 additions and 18 deletions
+1 -1
View File
@@ -221,7 +221,7 @@ cfg_io_util! {
/// ``` /// ```
fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B> fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where where
Self: Sized, Self: Sized + Unpin,
B: BufMut, B: BufMut,
{ {
read_buf(self, buf) read_buf(self, buf)
+1 -1
View File
@@ -180,7 +180,7 @@ cfg_io_util! {
/// ``` /// ```
fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B> fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where where
Self: Sized, Self: Sized + Unpin,
B: Buf, B: Buf,
{ {
write_buf(self, src) write_buf(self, src)
+5 -8
View File
@@ -8,7 +8,7 @@ use std::task::{Context, Poll};
pub(crate) fn read_buf<'a, R, B>(reader: &'a mut R, buf: &'a mut B) -> ReadBuf<'a, R, B> pub(crate) fn read_buf<'a, R, B>(reader: &'a mut R, buf: &'a mut B) -> ReadBuf<'a, R, B>
where where
R: AsyncRead, R: AsyncRead + Unpin,
B: BufMut, B: BufMut,
{ {
ReadBuf { reader, buf } ReadBuf { reader, buf }
@@ -26,16 +26,13 @@ cfg_io_util! {
impl<R, B> Future for ReadBuf<'_, R, B> impl<R, B> Future for ReadBuf<'_, R, B>
where where
R: AsyncRead, R: AsyncRead + Unpin,
B: BufMut, B: BufMut,
{ {
type Output = io::Result<usize>; type Output = io::Result<usize>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
// safety: no data is moved from self let me = &mut *self;
unsafe { Pin::new(&mut *me.reader).poll_read_buf(cx, me.buf)
let me = self.get_unchecked_mut();
Pin::new_unchecked(&mut *me.reader).poll_read_buf(cx, &mut me.buf)
}
} }
} }
+5 -8
View File
@@ -20,7 +20,7 @@ cfg_io_util! {
/// asynchronous manner, returning a future. /// asynchronous manner, returning a future.
pub(crate) fn write_buf<'a, W, B>(writer: &'a mut W, buf: &'a mut B) -> WriteBuf<'a, W, B> pub(crate) fn write_buf<'a, W, B>(writer: &'a mut W, buf: &'a mut B) -> WriteBuf<'a, W, B>
where where
W: AsyncWrite, W: AsyncWrite + Unpin,
B: Buf, B: Buf,
{ {
WriteBuf { writer, buf } WriteBuf { writer, buf }
@@ -28,16 +28,13 @@ where
impl<W, B> Future for WriteBuf<'_, W, B> impl<W, B> Future for WriteBuf<'_, W, B>
where where
W: AsyncWrite, W: AsyncWrite + Unpin,
B: Buf, B: Buf,
{ {
type Output = io::Result<usize>; type Output = io::Result<usize>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> { fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> {
// safety: no data is moved from self let me = &mut *self;
unsafe { Pin::new(&mut *me.writer).poll_write_buf(cx, me.buf)
let me = self.get_unchecked_mut();
Pin::new_unchecked(&mut *me.writer).poll_write_buf(cx, &mut me.buf)
}
} }
} }