diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2025-02-25 16:03:25 -0800 | 
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2025-02-25 16:03:25 -0800 | 
| commit | 0b119045b79a672bc6d8f18641c60fc8ce1b4585 (patch) | |
| tree | 69c63ecfec55b9576c34dc742e0c38f46f8a317a /rust/kernel/str.rs | |
| parent | 7f7573bd4f37d4edc168c5b5def0bc2a1951c657 (diff) | |
| parent | d082ecbc71e9e0bf49883ee4afd435a77a5101b6 (diff) | |
Merge tag 'v6.14-rc4' into next
Sync up with the mainline.
Diffstat (limited to 'rust/kernel/str.rs')
| -rw-r--r-- | rust/kernel/str.rs | 38 | 
1 files changed, 23 insertions, 15 deletions
| diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index d04c12a1426d..28e2201604d6 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -39,12 +39,13 @@ impl fmt::Display for BStr {      /// ```      /// # use kernel::{fmt, b_str, str::{BStr, CString}};      /// let ascii = b_str!("Hello, BStr!"); -    /// let s = CString::try_from_fmt(fmt!("{}", ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{}", ascii))?;      /// assert_eq!(s.as_bytes(), "Hello, BStr!".as_bytes());      ///      /// let non_ascii = b_str!("🦀"); -    /// let s = CString::try_from_fmt(fmt!("{}", non_ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{}", non_ascii))?;      /// assert_eq!(s.as_bytes(), "\\xf0\\x9f\\xa6\\x80".as_bytes()); +    /// # Ok::<(), kernel::error::Error>(())      /// ```      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {          for &b in &self.0 { @@ -70,12 +71,13 @@ impl fmt::Debug for BStr {      /// # use kernel::{fmt, b_str, str::{BStr, CString}};      /// // Embedded double quotes are escaped.      /// let ascii = b_str!("Hello, \"BStr\"!"); -    /// let s = CString::try_from_fmt(fmt!("{:?}", ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{:?}", ascii))?;      /// assert_eq!(s.as_bytes(), "\"Hello, \\\"BStr\\\"!\"".as_bytes());      ///      /// let non_ascii = b_str!("😺"); -    /// let s = CString::try_from_fmt(fmt!("{:?}", non_ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{:?}", non_ascii))?;      /// assert_eq!(s.as_bytes(), "\"\\xf0\\x9f\\x98\\xba\"".as_bytes()); +    /// # Ok::<(), kernel::error::Error>(())      /// ```      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {          f.write_char('"')?; @@ -189,7 +191,7 @@ impl CStr {          // to a `NUL`-terminated C string.          let len = unsafe { bindings::strlen(ptr) } + 1;          // SAFETY: Lifetime guaranteed by the safety precondition. -        let bytes = unsafe { core::slice::from_raw_parts(ptr as _, len as _) }; +        let bytes = unsafe { core::slice::from_raw_parts(ptr as _, len) };          // SAFETY: As `len` is returned by `strlen`, `bytes` does not contain interior `NUL`.          // As we have added 1 to `len`, the last byte is known to be `NUL`.          unsafe { Self::from_bytes_with_nul_unchecked(bytes) } @@ -248,7 +250,7 @@ impl CStr {      /// Returns a C pointer to the string.      #[inline]      pub const fn as_char_ptr(&self) -> *const crate::ffi::c_char { -        self.0.as_ptr() as _ +        self.0.as_ptr()      }      /// Convert the string to a byte slice without the trailing `NUL` byte. @@ -273,8 +275,9 @@ impl CStr {      ///      /// ```      /// # use kernel::str::CStr; -    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").unwrap(); +    /// let cstr = CStr::from_bytes_with_nul(b"foo\0")?;      /// assert_eq!(cstr.to_str(), Ok("foo")); +    /// # Ok::<(), kernel::error::Error>(())      /// ```      #[inline]      pub fn to_str(&self) -> Result<&str, core::str::Utf8Error> { @@ -384,12 +387,13 @@ impl fmt::Display for CStr {      /// # use kernel::str::CStr;      /// # use kernel::str::CString;      /// let penguin = c_str!("🐧"); -    /// let s = CString::try_from_fmt(fmt!("{}", penguin)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{}", penguin))?;      /// assert_eq!(s.as_bytes_with_nul(), "\\xf0\\x9f\\x90\\xa7\0".as_bytes());      ///      /// let ascii = c_str!("so \"cool\""); -    /// let s = CString::try_from_fmt(fmt!("{}", ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{}", ascii))?;      /// assert_eq!(s.as_bytes_with_nul(), "so \"cool\"\0".as_bytes()); +    /// # Ok::<(), kernel::error::Error>(())      /// ```      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {          for &c in self.as_bytes() { @@ -413,13 +417,14 @@ impl fmt::Debug for CStr {      /// # use kernel::str::CStr;      /// # use kernel::str::CString;      /// let penguin = c_str!("🐧"); -    /// let s = CString::try_from_fmt(fmt!("{:?}", penguin)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{:?}", penguin))?;      /// assert_eq!(s.as_bytes_with_nul(), "\"\\xf0\\x9f\\x90\\xa7\"\0".as_bytes());      ///      /// // Embedded double quotes are escaped.      /// let ascii = c_str!("so \"cool\""); -    /// let s = CString::try_from_fmt(fmt!("{:?}", ascii)).unwrap(); +    /// let s = CString::try_from_fmt(fmt!("{:?}", ascii))?;      /// assert_eq!(s.as_bytes_with_nul(), "\"so \\\"cool\\\"\"\0".as_bytes()); +    /// # Ok::<(), kernel::error::Error>(())      /// ```      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {          f.write_str("\"")?; @@ -522,6 +527,7 @@ macro_rules! c_str {  }  #[cfg(test)] +#[expect(clippy::items_after_test_module)]  mod tests {      use super::*; @@ -547,7 +553,7 @@ mod tests {          })      } -    const ALL_ASCII_CHARS: &'static str = +    const ALL_ASCII_CHARS: &str =          "\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\x09\\x0a\\x0b\\x0c\\x0d\\x0e\\x0f\          \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f \          !\"#$%&'()*+,-./0123456789:;<=>?@\ @@ -581,6 +587,7 @@ mod tests {      fn test_cstr_as_str_unchecked() {          let good_bytes = b"\xf0\x9f\x90\xA7\0";          let checked_cstr = CStr::from_bytes_with_nul(good_bytes).unwrap(); +        // SAFETY: The contents come from a string literal which contains valid UTF-8.          let unchecked_str = unsafe { checked_cstr.as_str_unchecked() };          assert_eq!(unchecked_str, "🐧");      } @@ -799,16 +806,17 @@ impl fmt::Write for Formatter {  /// ```  /// use kernel::{str::CString, fmt};  /// -/// let s = CString::try_from_fmt(fmt!("{}{}{}", "abc", 10, 20)).unwrap(); +/// let s = CString::try_from_fmt(fmt!("{}{}{}", "abc", 10, 20))?;  /// assert_eq!(s.as_bytes_with_nul(), "abc1020\0".as_bytes());  ///  /// let tmp = "testing"; -/// let s = CString::try_from_fmt(fmt!("{tmp}{}", 123)).unwrap(); +/// let s = CString::try_from_fmt(fmt!("{tmp}{}", 123))?;  /// assert_eq!(s.as_bytes_with_nul(), "testing123\0".as_bytes());  ///  /// // This fails because it has an embedded `NUL` byte.  /// let s = CString::try_from_fmt(fmt!("a\0b{}", 123));  /// assert_eq!(s.is_ok(), false); +/// # Ok::<(), kernel::error::Error>(())  /// ```  pub struct CString {      buf: KVec<u8>, @@ -838,7 +846,7 @@ impl CString {          // SAFETY: The buffer is valid for read because `f.bytes_written()` is bounded by `size`          // (which the minimum buffer size) and is non-zero (we wrote at least the `NUL` terminator)          // so `f.bytes_written() - 1` doesn't underflow. -        let ptr = unsafe { bindings::memchr(buf.as_ptr().cast(), 0, (f.bytes_written() - 1) as _) }; +        let ptr = unsafe { bindings::memchr(buf.as_ptr().cast(), 0, f.bytes_written() - 1) };          if !ptr.is_null() {              return Err(EINVAL);          } | 
