diff options
Diffstat (limited to 'vendor/rustix/src/path')
-rw-r--r-- | vendor/rustix/src/path/arg.rs | 140 |
1 files changed, 129 insertions, 11 deletions
diff --git a/vendor/rustix/src/path/arg.rs b/vendor/rustix/src/path/arg.rs index 64091611c..3b0ad91ae 100644 --- a/vendor/rustix/src/path/arg.rs +++ b/vendor/rustix/src/path/arg.rs @@ -5,16 +5,13 @@ //! to rustix APIs with string arguments, and it allows rustix to implement //! NUL-termination without the need for copying where possible. -use crate::ffi::{CStr, CString}; +use crate::ffi::CStr; use crate::io; #[cfg(feature = "itoa")] use crate::path::DecInt; use crate::path::SMALL_PATH_BUFFER_SIZE; -use alloc::borrow::Cow; -#[cfg(feature = "itoa")] +#[cfg(all(feature = "alloc", feature = "itoa"))] use alloc::borrow::ToOwned; -use alloc::string::String; -use alloc::vec::Vec; use core::mem::MaybeUninit; use core::{ptr, slice, str}; #[cfg(feature = "std")] @@ -29,6 +26,10 @@ use std::os::vxworks::ext::ffi::{OsStrExt, OsStringExt}; use std::os::wasi::ffi::{OsStrExt, OsStringExt}; #[cfg(feature = "std")] use std::path::{Component, Components, Iter, Path, PathBuf}; +#[cfg(feature = "alloc")] +use {crate::ffi::CString, alloc::borrow::Cow}; +#[cfg(feature = "alloc")] +use {alloc::string::String, alloc::vec::Vec}; /// A trait for passing path arguments. /// @@ -65,15 +66,18 @@ pub trait Arg { /// Returns a view of this string as a string slice. fn as_str(&self) -> io::Result<&str>; - /// Returns a potentially-lossy rendering of this string as a `Cow<'_, - /// str>`. + /// Returns a potentially-lossy rendering of this string as a + /// `Cow<'_, str>`. + #[cfg(feature = "alloc")] fn to_string_lossy(&self) -> Cow<'_, str>; /// Returns a view of this string as a maybe-owned [`CStr`]. + #[cfg(feature = "alloc")] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>>; /// Consumes `self` and returns a view of this string as a maybe-owned /// [`CStr`]. + #[cfg(feature = "alloc")] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where Self: 'b; @@ -91,11 +95,13 @@ impl Arg for &str { Ok(self) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Cow::Borrowed(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -103,6 +109,7 @@ impl Arg for &str { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -123,17 +130,20 @@ impl Arg for &str { } } +#[cfg(feature = "alloc")] impl Arg for &String { #[inline] fn as_str(&self) -> io::Result<&str> { Ok(self) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Cow::Borrowed(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -141,6 +151,7 @@ impl Arg for &String { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -159,17 +170,20 @@ impl Arg for &String { } } +#[cfg(feature = "alloc")] impl Arg for String { #[inline] fn as_str(&self) -> io::Result<&str> { Ok(self) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Cow::Borrowed(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -177,6 +191,7 @@ impl Arg for String { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -204,11 +219,13 @@ impl Arg for &OsStr { self.to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { OsStr::to_string_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -216,6 +233,7 @@ impl Arg for &OsStr { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -243,11 +261,13 @@ impl Arg for &OsString { OsString::as_os_str(self).to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_os_str().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -256,6 +276,7 @@ impl Arg for &OsString { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -281,11 +302,13 @@ impl Arg for OsString { self.as_os_str().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_os_str().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -293,6 +316,7 @@ impl Arg for OsString { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -320,11 +344,13 @@ impl Arg for &Path { self.as_os_str().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Path::to_string_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -332,6 +358,7 @@ impl Arg for &Path { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -362,11 +389,13 @@ impl Arg for &PathBuf { .ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_path().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -375,6 +404,7 @@ impl Arg for &PathBuf { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -400,11 +430,13 @@ impl Arg for PathBuf { self.as_os_str().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_os_str().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -412,6 +444,7 @@ impl Arg for PathBuf { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -441,16 +474,19 @@ impl Arg for &CStr { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { CStr::to_string_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Borrowed(self)) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -469,22 +505,26 @@ impl Arg for &CStr { } } +#[cfg(feature = "alloc")] impl Arg for &CString { #[inline] fn as_str(&self) -> io::Result<&str> { unimplemented!() } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { unimplemented!() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Borrowed(self)) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -503,22 +543,26 @@ impl Arg for &CString { } } +#[cfg(feature = "alloc")] impl Arg for CString { #[inline] fn as_str(&self) -> io::Result<&str> { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { CStr::to_string_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Borrowed(self)) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -537,17 +581,20 @@ impl Arg for CString { } } +#[cfg(feature = "alloc")] impl<'a> Arg for Cow<'a, str> { #[inline] fn as_str(&self) -> io::Result<&str> { Ok(self) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Cow::Borrowed(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -555,6 +602,7 @@ impl<'a> Arg for Cow<'a, str> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -580,17 +628,20 @@ impl<'a> Arg for Cow<'a, str> { } #[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl<'a> Arg for Cow<'a, OsStr> { #[inline] fn as_str(&self) -> io::Result<&str> { (**self).to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { (**self).to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -598,6 +649,7 @@ impl<'a> Arg for Cow<'a, OsStr> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -622,23 +674,27 @@ impl<'a> Arg for Cow<'a, OsStr> { } } +#[cfg(feature = "alloc")] impl<'a> Arg for Cow<'a, CStr> { #[inline] fn as_str(&self) -> io::Result<&str> { self.to_str().map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { let borrow: &CStr = core::borrow::Borrow::borrow(self); borrow.to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Borrowed(self)) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -664,11 +720,13 @@ impl<'a> Arg for Component<'a> { self.as_os_str().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_os_str().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -676,6 +734,7 @@ impl<'a> Arg for Component<'a> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -703,11 +762,13 @@ impl<'a> Arg for Components<'a> { self.as_path().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_path().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -716,6 +777,7 @@ impl<'a> Arg for Components<'a> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -744,11 +806,13 @@ impl<'a> Arg for Iter<'a> { self.as_path().to_str().ok_or(io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { self.as_path().to_string_lossy() } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -757,6 +821,7 @@ impl<'a> Arg for Iter<'a> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -784,11 +849,13 @@ impl Arg for &[u8] { str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { String::from_utf8_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -796,6 +863,7 @@ impl Arg for &[u8] { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -816,17 +884,20 @@ impl Arg for &[u8] { } } +#[cfg(feature = "alloc")] impl Arg for &Vec<u8> { #[inline] fn as_str(&self) -> io::Result<&str> { str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { String::from_utf8_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -834,6 +905,7 @@ impl Arg for &Vec<u8> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -854,17 +926,20 @@ impl Arg for &Vec<u8> { } } +#[cfg(feature = "alloc")] impl Arg for Vec<u8> { #[inline] fn as_str(&self) -> io::Result<&str> { str::from_utf8(self).map_err(|_utf8_err| io::Errno::INVAL) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { String::from_utf8_lossy(self) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Owned( @@ -872,6 +947,7 @@ impl Arg for Vec<u8> { )) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -899,16 +975,19 @@ impl Arg for DecInt { Ok(self.as_str()) } + #[cfg(feature = "alloc")] #[inline] fn to_string_lossy(&self) -> Cow<'_, str> { Cow::Borrowed(self.as_str()) } + #[cfg(feature = "alloc")] #[inline] fn as_cow_c_str(&self) -> io::Result<Cow<'_, CStr>> { Ok(Cow::Borrowed(self.as_c_str())) } + #[cfg(feature = "alloc")] #[inline] fn into_c_str<'b>(self) -> io::Result<Cow<'b, CStr>> where @@ -961,19 +1040,58 @@ where } // 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. + // 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 -/// to `PATH_MAX`, but we let the OS enforce that. +/// The slow path which handles any length. In theory OS's only support up to +/// `PATH_MAX`, but we let the OS enforce that. +#[allow(unsafe_code, clippy::int_plus_one)] #[cold] fn with_c_str_slow_path<T, F>(bytes: &[u8], f: F) -> io::Result<T> where F: FnOnce(&CStr) -> io::Result<T>, { - f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) + #[cfg(feature = "alloc")] + { + f(&CString::new(bytes).map_err(|_cstr_err| io::Errno::INVAL)?) + } + + #[cfg(not(feature = "alloc"))] + { + #[cfg(libc)] + const LARGE_PATH_BUFFER_SIZE: usize = libc::PATH_MAX as usize; + #[cfg(linux_raw)] + const LARGE_PATH_BUFFER_SIZE: usize = linux_raw_sys::general::PATH_MAX as usize; + + // Taken from + // <https://github.com/rust-lang/rust/blob/a00f8ba7fcac1b27341679c51bf5a3271fa82df3/library/std/src/sys/common/small_c_string.rs> + let mut buf = MaybeUninit::<[u8; LARGE_PATH_BUFFER_SIZE]>::uninit(); + let buf_ptr = buf.as_mut_ptr().cast::<u8>(); + + // This helps test our safety condition below. + if bytes.len() + 1 > LARGE_PATH_BUFFER_SIZE { + return Err(io::Errno::NAMETOOLONG); + } + + // SAFETY: `bytes.len() < LARGE_PATH_BUFFER_SIZE` which means we have space + // for `bytes.len() + 1` u8s: + 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), + } + } } |