io: deny unsafe_op_in_unsafe_fn

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2022-12-07 11:20:25 +01:00
parent 8316fd3899
commit a7d84effc5
5 changed files with 37 additions and 23 deletions

View File

@ -3,6 +3,8 @@
//! The [`ReadExt`] trait provides additional operations for handling byte buffers for types //! The [`ReadExt`] trait provides additional operations for handling byte buffers for types
//! implementing [`Read`](std::io::Read). //! implementing [`Read`](std::io::Read).
#![deny(unsafe_op_in_unsafe_fn)]
mod read; mod read;
pub use read::ReadExt; pub use read::ReadExt;

View File

@ -267,30 +267,34 @@ impl<R: io::Read> ReadExt for R {
unsafe fn read_host_value<T: Endian>(&mut self) -> io::Result<T> { unsafe fn read_host_value<T: Endian>(&mut self) -> io::Result<T> {
let mut value = std::mem::MaybeUninit::<T>::uninit(); let mut value = std::mem::MaybeUninit::<T>::uninit();
self.read_exact(std::slice::from_raw_parts_mut( unsafe {
value.as_mut_ptr() as *mut u8, self.read_exact(std::slice::from_raw_parts_mut(
mem::size_of::<T>(), value.as_mut_ptr() as *mut u8,
))?; mem::size_of::<T>(),
Ok(value.assume_init()) ))?;
Ok(value.assume_init())
}
} }
unsafe fn read_le_value<T: Endian>(&mut self) -> io::Result<T> { unsafe fn read_le_value<T: Endian>(&mut self) -> io::Result<T> {
Ok(self.read_host_value::<T>()?.from_le()) unsafe { Ok(self.read_host_value::<T>()?.from_le()) }
} }
unsafe fn read_be_value<T: Endian>(&mut self) -> io::Result<T> { unsafe fn read_be_value<T: Endian>(&mut self) -> io::Result<T> {
Ok(self.read_host_value::<T>()?.from_be()) unsafe { Ok(self.read_host_value::<T>()?.from_be()) }
} }
unsafe fn read_host_value_boxed<T>(&mut self) -> io::Result<Box<T>> { unsafe fn read_host_value_boxed<T>(&mut self) -> io::Result<Box<T>> {
// FIXME: Change this once #![feature(new_uninit)] lands for Box<T>! // FIXME: Change this once #![feature(new_uninit)] lands for Box<T>!
let ptr = std::alloc::alloc(std::alloc::Layout::new::<T>()) as *mut T; unsafe {
self.read_exact(std::slice::from_raw_parts_mut( let ptr = std::alloc::alloc(std::alloc::Layout::new::<T>()) as *mut T;
ptr as *mut u8, self.read_exact(std::slice::from_raw_parts_mut(
mem::size_of::<T>(), ptr as *mut u8,
))?; mem::size_of::<T>(),
Ok(Box::from_raw(ptr)) ))?;
Ok(Box::from_raw(ptr))
}
} }
fn read_exact_or_eof(&mut self, mut buf: &mut [u8]) -> io::Result<bool> { fn read_exact_or_eof(&mut self, mut buf: &mut [u8]) -> io::Result<bool> {

View File

@ -97,7 +97,9 @@ impl ByteVecExt for Vec<u8> {
let old_len = self.len(); let old_len = self.len();
self.reserve(more); self.reserve(more);
let total = old_len + more; let total = old_len + more;
self.set_len(total); unsafe {
self.set_len(total);
}
&mut self[old_len..] &mut self[old_len..]
} }
@ -105,7 +107,9 @@ impl ByteVecExt for Vec<u8> {
if new_size <= self.len() { if new_size <= self.len() {
self.truncate(new_size); self.truncate(new_size);
} else { } else {
self.grow_uninitialized(new_size - self.len()); unsafe {
self.grow_uninitialized(new_size - self.len());
}
} }
} }
} }

View File

@ -52,8 +52,10 @@ pub use byte_vec::ByteVecExt;
/// marked as unsafe for good measure. /// marked as unsafe for good measure.
#[inline] #[inline]
pub unsafe fn uninitialized(len: usize) -> Vec<u8> { pub unsafe fn uninitialized(len: usize) -> Vec<u8> {
let data = std::alloc::alloc(std::alloc::Layout::array::<u8>(len).unwrap()); unsafe {
Vec::from_raw_parts(data as *mut u8, len, len) let data = std::alloc::alloc(std::alloc::Layout::array::<u8>(len).unwrap());
Vec::from_raw_parts(data as *mut u8, len, len)
}
} }
/// Shortcut to zero out a slice of bytes. /// Shortcut to zero out a slice of bytes.

View File

@ -167,17 +167,19 @@ pub trait WriteExt {
impl<W: io::Write> WriteExt for W { impl<W: io::Write> WriteExt for W {
unsafe fn write_host_value<T: Endian>(&mut self, value: T) -> io::Result<()> { unsafe fn write_host_value<T: Endian>(&mut self, value: T) -> io::Result<()> {
self.write_all(std::slice::from_raw_parts( unsafe {
&value as *const T as *const u8, self.write_all(std::slice::from_raw_parts(
std::mem::size_of::<T>(), &value as *const T as *const u8,
)) std::mem::size_of::<T>(),
))
}
} }
unsafe fn write_le_value<T: Endian>(&mut self, value: T) -> io::Result<()> { unsafe fn write_le_value<T: Endian>(&mut self, value: T) -> io::Result<()> {
self.write_host_value::<T>(value.to_le()) unsafe { self.write_host_value::<T>(value.to_le()) }
} }
unsafe fn write_be_value<T: Endian>(&mut self, value: T) -> io::Result<()> { unsafe fn write_be_value<T: Endian>(&mut self, value: T) -> io::Result<()> {
self.write_host_value::<T>(value.to_be()) unsafe { self.write_host_value::<T>(value.to_be()) }
} }
} }