Skip to content

Commit

Permalink
Add UninitSlice::as_uninit_slice_mut()
Browse files Browse the repository at this point in the history
This adds an unsafe method to convert a `&mut UninitSlice` into a
`&mut [MaybeUninit<u8>]`. This method is unsafe because some of the
bytes in the slice may be initialized, and the caller should not
overwrite them with uninitialized bytes.

This came about when auditing [tokio-util's udp frame], where they want
to pass the unitialized portion of a `BytesMut` to [ReadBuf::uninit].
They need to do this unsafe pointer casting in a few places, which
complicates audits. This method lets us document the safety invariants
the caller needs to maintain when doing this conversion.

[tokio-util's udp frame]: https:/tokio-rs/tokio/blob/master/tokio-util/src/udp/frame.rs#L87
[ReadBuf::uninit]: https://docs.rs/tokio/latest/tokio/io/struct.ReadBuf.html#method.uninit
  • Loading branch information
erickt committed May 5, 2022
1 parent 0ce4fe3 commit 39aa8fe
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/buf/uninit_slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,29 @@ impl UninitSlice {
self.0.as_mut_ptr() as *mut _
}

/// Return a `&mut [MaybeUninit<u8>] to this slice's buffer.
///
/// # Safety
///
/// The caller **must not** read from the referenced memory and **must not**
/// write **uninitialized** bytes to the slice either.
///
/// # Examples
///
/// ```
/// use bytes::BufMut;
///
/// let mut data = [0, 1, 2];
/// let mut slice = &mut data[..];
/// unsafe {
/// let uninit_slice = BufMut::chunk_mut(&mut slice).as_uninit_slice_mut();
/// };
/// ```
#[inline]
pub unsafe fn as_uninit_slice_mut<'a>(&'a mut self) -> &'a mut [MaybeUninit<u8>] {
&mut *(self as *mut _ as *mut [MaybeUninit<u8>])
}

/// Returns the number of bytes in the slice.
///
/// # Examples
Expand Down

0 comments on commit 39aa8fe

Please sign in to comment.