diff libpam-sys/src/structs.rs @ 117:20f7712a6857

Neaten up libpam-sys BinaryPayload buffer management.
author Paul Fisher <paul@pfish.zone>
date Sun, 29 Jun 2025 18:48:14 -0400
parents bb465393621f
children 39760dfc9b3b
line wrap: on
line diff
--- a/libpam-sys/src/structs.rs	Sun Jun 29 18:27:51 2025 -0400
+++ b/libpam-sys/src/structs.rs	Sun Jun 29 18:48:14 2025 -0400
@@ -34,30 +34,43 @@
         buf[5..].copy_from_slice(data)
     }
 
-    /// The size of the message contained in the buffer.
-    fn len(&self) -> usize {
-        self.total_bytes().saturating_sub(5)
-    }
-
     /// The total storage needed for the message, including header.
     pub fn total_bytes(&self) -> usize {
         u32::from_be_bytes(self.total_bytes_u32be) as usize
     }
 
-    /// Gets the contents of the BinaryMessage stored at the given pointer.
+    /// Gets the total byte buffer of the BinaryMessage stored at the pointer.
     ///
     /// The returned data slice is borrowed from where the pointer points to.
     ///
     /// # Safety
     ///
     /// - The pointer must point to a valid `BinaryPayload`.
-    /// - The borrowed data must not outlive the validity of this pointer.
+    /// - The borrowed data must not outlive the pointer's validity.
+    pub unsafe fn buffer_of<'a>(ptr: *const Self) -> &'a [u8] {
+        let header: &Self = ptr.as_ref().unwrap_unchecked();
+        slice::from_raw_parts(ptr.cast(), header.total_bytes().max(5))
+    }
+
+    /// Gets the contents of the BinaryMessage stored at the given pointer.
+    ///
+    /// The returned data slice is borrowed from where the pointer points to.
+    /// This is a cheap operation and doesn't do *any* copying.
+    ///
+    /// We don't take a `&self` reference here because accessing beyond
+    /// the range of the `Self` data (i.e., beyond the 5 bytes of `self`)
+    /// is undefined behavior. Instead, you have to pass a raw pointer
+    /// directly to the data.
+    ///
+    /// # Safety
+    ///
+    /// - The pointer must point to a valid `BinaryPayload`.
+    /// - The borrowed data must not outlive the pointer's validity.
     pub unsafe fn contents<'a>(ptr: *const Self) -> (u8, &'a [u8]) {
         let header: &Self = ptr.as_ref().unwrap_unchecked();
-        let typ = header.data_type;
         (
-            typ,
-            slice::from_raw_parts(ptr.cast::<u8>().offset(5), header.len()),
+            header.data_type,
+            &Self::buffer_of(ptr)[5..]
         )
     }
 }