uninit/read/
mod.rs

1//! Read into uninitialized bytes logic.
2
3use_prelude!();
4
5use ::std::io::Read;
6
7/// Trait for a [`Read`](https://doc.rust-lang.org/std/io/trait.Read.html)able
8/// type that can output the bytes read into
9/// [uninitialised memory][`MaybeUninit`].
10///
11/// # Safety (to implement) / Guarantees (for users of `impl ReadIntoUninit` types)
12///
13/// The trait is `unsafe` (to implement) because it **needs to guarantee** to
14/// users of generic `R : ReadIntoUninit` code (that may use `unsafe` code
15/// relying on it!) that:
16///
17///   - `if let Ok(init_buf) = self.read_into_uninit(buf)`, then it must be
18///     sound to:
19///
20///     ```rust
21///     # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
22///     unsafe {
23///         buf.get_out_unchecked(.. init_buf.len()).assume_init()
24///     }
25///     # }
26///     ```
27///
28///   - `if self.read_into_uninit_exact(buf).is_ok()`, then it must be
29///     sound to: `buf.assume_init()`.
30///
31/// # Counterexample
32///
33/// ```rust,no_run
34/// #![feature(specialization)]
35/// use ::uninit::{prelude::*,
36///     read::{auto_impl, ReadIntoUninit},
37/// };
38///
39/// pub
40/// struct Evil;
41///
42/// auto_impl! { #[derived_from(ReadIntoUninit)] impl Read for Evil }
43/// unsafe // unsound!
44/// impl ReadIntoUninit for Evil {
45///     fn read_into_uninit<'buf> (
46///         self: &'_ mut Self,
47///         buf: Out<'buf, [u8]>,
48///     ) -> ::std::io::Result<&'buf mut [u8]>
49///     {
50///         Ok(Box::leak(vec![0; buf.len()].into_boxed_slice()))
51///     }
52/// }
53/// ```
54///
55/// Indeed, with such an impl, the following function could cause UB, when
56/// instanced with `R = Evil`:
57///
58/// ```rust
59/// use ::uninit::{prelude::*, read::ReadIntoUninit};
60///
61/// fn read_byte<R> (reader: &'_ mut R)
62///   -> ::std::io::Result<u8>
63/// where
64///     R : ReadIntoUninit,
65/// {
66///     let mut byte = MaybeUninit::uninit();
67///     reader.read_into_uninit_exact(::std::slice::from_mut(&mut byte).as_out())?;
68///     Ok(unsafe {
69///         // Safety: Guaranteed by `ReadIntoUninit` contract
70///         byte.assume_init()
71///     })
72/// }
73/// ```
74pub unsafe trait ReadIntoUninit: Read
75// Safety: `.read_into_uninit_exact()` delegates to `.read_into_uninit()`.
76{
77    /// Single attempt to read bytes from `Self` into `buf`.
78    ///
79    /// On success, it returns the bytes having been read.
80    ///
81    /// # Guarantees (that `unsafe` code may rely on)
82    ///
83    ///   - `if let Ok(init_buf) = self.read_into_uninit(buf)`, then it is
84    ///     sound to:
85    ///
86    ///     ```rust
87    ///     # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
88    ///     unsafe {
89    ///         buf.get_out_unchecked(.. init_buf.len()).assume_init()
90    ///     }
91    ///     # }
92    ///     ```
93    ///
94    /// This is not guaranteed to read `buf.len()` bytes, see the docs of
95    /// [`.read()`][`Read::read`] for more information.
96    fn read_into_uninit<'buf>(
97        self: &'_ mut Self,
98        buf: Out<'buf, [u8]>,
99    ) -> io::Result<&'buf mut [u8]>;
100
101    /// Attempts to _fill_ `buf` through multiple `.read()` calls if necessary.
102    ///
103    /// On success, it returns the bytes having been read.
104    ///
105    /// # Guarantees (that `unsafe` code may rely on)
106    ///
107    ///   - `if self.read_into_uninit_exact(buf).is_ok()`, then it is
108    ///     sound to: `buf.assume_init()`.
109    ///
110    /// See the docs of [`.read_exact()`][`Read::read_exact`] for more
111    /// information.
112    fn read_into_uninit_exact<'buf>(
113        self: &'_ mut Self,
114        mut buf: Out<'buf, [u8]>,
115    ) -> io::Result<&'buf mut [u8]> {
116        {
117            let mut buf = buf.reborrow();
118            while buf.is_empty().not() {
119                match self.read_into_uninit(buf.r()).map(|it| it.len()) {
120                    Ok(0) => {
121                        return Err(io::Error::new(
122                            io::ErrorKind::UnexpectedEof,
123                            "failed to fill whole buffer",
124                        ));
125                    }
126                    Ok(n) => {
127                        // buf = &mut buf[n ..];
128                        buf = buf.get_out(n..).unwrap();
129                    }
130                    Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
131                    Err(e) => {
132                        return Err(e);
133                    }
134                }
135            }
136        }
137        Ok(unsafe {
138            // # Safety
139            //
140            //   - this is the "concatenation" of all the "buf[.. n]"
141            //     initialisation witnesses.
142            buf.assume_init()
143        })
144    }
145
146    /// Chains / concats two `ReadIntoUninit` readers into one.
147    #[cfg(feature = "chain")]
148    #[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
149    fn chain<R: ReadIntoUninit>(self: Self, next: R) -> chain::Chain<Self, R>
150    where
151        Self: Sized,
152    {
153        chain::Chain {
154            first: self,
155            second: next,
156            first_done: false,
157        }
158    }
159}
160
161/// Helper macro to alleviate the code duplication from implementing both
162/// `Read` and `ReadIntoUninit`.
163///
164/// Once some type `T` implements `ReadIntoUninit`, you can derive `Read` by
165/// doing:
166///
167/// ```rust
168/// # macro_rules! ignore {($($t:tt)*) => ()} ignore! {
169/// ::uninit::read::auto_impl! {
170///     #[derived_from(ReadIntoUninit)]
171///     impl Read for X
172/// }
173/// // and if X is generic, over, for instance, `Generics`
174/// ::uninit::read::auto_impl! {
175///     #[derived_from(ReadIntoUninit)]
176///     impl[Generics] Read for X<Generics>
177/// }
178/// # }
179/// ```
180#[doc(hidden)]
181#[macro_export]
182macro_rules! _private_auto_impl {(
183    #[derived_from(ReadIntoUninit)]
184    impl $( [$($generics:tt)*] )? Read for $T:ty
185    $(
186        where
187        $($where_clause:tt)*
188    )?
189) => (
190    impl$(<$($generics)*>)? $crate::std::io::Read for $T
191    where
192        $( $($where_clause)* )?
193    {
194        #[inline]
195        fn read (self: &'_ mut Self, buf: &'_ mut [u8])
196            -> $crate::std::io::Result<usize>
197        {
198            <Self as $crate::read::ReadIntoUninit>::read_into_uninit(
199                self,
200                buf.as_out(),
201            ).map(|x| x.len())
202        }
203
204        #[inline]
205        fn read_exact (self: &'_ mut Self, buf: &'_ mut [u8])
206            -> $crate::std::io::Result<()>
207        {
208            <Self as $crate::read::ReadIntoUninit>::read_into_uninit_exact(
209                self,
210                buf.as_out(),
211            ).map(drop)
212        }
213    }
214)}
215#[doc(inline)]
216pub use _private_auto_impl as auto_impl;
217
218pub use crate::extension_traits::VecExtendFromReader;
219
220mod impls;
221
222#[cfg(feature = "chain")]
223#[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
224pub mod chain {
225    #![allow(missing_docs)]
226    use super::*;
227
228    #[cfg_attr(feature = "nightly", doc(cfg(feature = "chain")))]
229    #[derive(Debug)]
230    pub struct Chain<R1, R2>
231    where
232        R1: ReadIntoUninit,
233        R2: ReadIntoUninit,
234    {
235        pub(super) first: R1,
236
237        pub(super) second: R2,
238
239        pub(super) first_done: bool,
240    }
241
242    impl<R1, R2> Chain<R1, R2>
243    where
244        R1: ReadIntoUninit,
245        R2: ReadIntoUninit,
246    {
247        pub fn into_inner(self: Self) -> (R1, R2) {
248            let Self { first, second, .. } = self;
249            (first, second)
250        }
251
252        pub fn get_ref(self: &'_ Self) -> (&'_ R1, &'_ R2) {
253            let Self { first, second, .. } = self;
254            (first, second)
255        }
256    }
257
258    unsafe impl<R1, R2> ReadIntoUninit for Chain<R1, R2>
259    where
260        R1: ReadIntoUninit,
261        R2: ReadIntoUninit,
262    {
263        fn read_into_uninit<'buf>(
264            self: &'_ mut Self,
265            mut buf: Out<'buf, [u8]>,
266        ) -> io::Result<&'buf mut [u8]> {
267            let len = buf.len();
268            if len == 0 {
269                return Ok(buf.copy_from_slice(&[]));
270            }
271            if self.first_done.not() {
272                let buf_ = self.first.read_into_uninit(buf.r())?;
273                if buf_.is_empty() {
274                    self.first_done = true;
275                } else {
276                    return unsafe {
277                        // Safety: `buf_` has been a witness of the
278                        // initialization of these bytes.
279                        let len = buf_.len();
280                        let buf = buf.get_out(..len).unwrap();
281                        Ok(buf.assume_init())
282                    };
283                }
284            }
285            self.second.read_into_uninit(buf)
286        }
287    }
288
289    super::auto_impl! {
290        #[derived_from(ReadIntoUninit)]
291        impl[R1, R2] Read for Chain<R1, R2>
292        where
293            R1 : ReadIntoUninit,
294            R2 : ReadIntoUninit,
295    }
296}