diff options
Diffstat (limited to 'vendor/rustix/src/path')
-rw-r--r-- | vendor/rustix/src/path/arg.rs | 28 | ||||
-rw-r--r-- | vendor/rustix/src/path/dec_int.rs | 2 |
2 files changed, 24 insertions, 6 deletions
diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs index 7f66f71f2..0ea673d19 100644 --- a/vendor/rustix/src/path/arg.rs +++ b/vendor/rustix/src/path/arg.rs @@ -15,7 +15,8 @@ use alloc::borrow::Cow; use alloc::borrow::ToOwned; use alloc::string::String; use alloc::vec::Vec; -use core::str; +use core::mem::MaybeUninit; +use core::{ptr, slice, str}; #[cfg(feature = "std")] use std::ffi::{OsStr, OsString}; #[cfg(feature = "std")] @@ -931,6 +932,7 @@ impl Arg for DecInt { } /// Runs a closure with `bytes` passed in as a `&CStr`. +#[allow(unsafe_code, clippy::int_plus_one)] #[inline] fn with_c_str<T, F>(bytes: &[u8], f: F) -> io::Result<T> where @@ -946,10 +948,26 @@ where if bytes.len() >= SMALL_PATH_BUFFER_SIZE { return with_c_str_slow_path(bytes, f); } - let mut buffer: [u8; SMALL_PATH_BUFFER_SIZE] = [0_u8; SMALL_PATH_BUFFER_SIZE]; - // Copy the bytes in; the buffer already has zeros for the trailing NUL. - buffer[..bytes.len()].copy_from_slice(bytes); - f(CStr::from_bytes_with_nul(&buffer[..=bytes.len()]).map_err(|_cstr_err| io::Errno::INVAL)?) + + // Taken from + // https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs + let mut buf = MaybeUninit::<[u8; SMALL_PATH_BUFFER_SIZE]>::uninit(); + let buf_ptr = buf.as_mut_ptr() as *mut u8; + + // SAFETY: bytes.len() < SMALL_PATH_BUFFER_SIZE which means we have space for + // bytes.len() + 1 u8s: + debug_assert!(bytes.len() + 1 <= SMALL_PATH_BUFFER_SIZE); + unsafe { + ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); + buf_ptr.add(bytes.len()).write(0); + } + + // SAFETY: we just wrote the bytes above and they will remain valid for the + // duration of f b/c buf doesn't get dropped until the end of the function. + match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { + Ok(s) => f(s), + Err(_) => Err(io::Errno::INVAL), + } } /// The slow path which handles any length. In theory OS's only support up diff --git a/vendor/rustix/src/path/dec_int.rs b/vendor/rustix/src/path/dec_int.rs index 4006fb06c..d0975694b 100644 --- a/vendor/rustix/src/path/dec_int.rs +++ b/vendor/rustix/src/path/dec_int.rs @@ -6,8 +6,8 @@ //! `str::from_utf8_unchecked`on the buffer that it filled itself. #![allow(unsafe_code)] +use crate::backend::fd::{AsFd, AsRawFd}; use crate::ffi::CStr; -use crate::imp::fd::{AsFd, AsRawFd}; #[cfg(feature = "std")] use core::fmt; use core::fmt::Write; |