diff src/handle.rs @ 143:ebb71a412b58

Turn everything into OsString and Just Walk Out! for strings with nul. To reduce the hazard surface of the API, this replaces most uses of &str with &OsStr (and likewise with String/OsString). Also, I've decided that instead of dealing with callers putting `\0` in their parameters, I'm going to follow the example of std::env and Just Walk Out! (i.e., panic!()). This makes things a lot less annoying for both me and (hopefully) users.
author Paul Fisher <paul@pfish.zone>
date Sat, 05 Jul 2025 22:12:46 -0400
parents a508a69c068a
children 56b559b7ecea
line wrap: on
line diff
--- a/src/handle.rs	Sat Jul 05 21:49:27 2025 -0400
+++ b/src/handle.rs	Sat Jul 05 22:12:46 2025 -0400
@@ -5,6 +5,7 @@
 use crate::environ::{EnvironMap, EnvironMapMut};
 use crate::logging::{Level, Location};
 use crate::{guide, linklist, man7, manbsd, stdlinks};
+use std::ffi::{OsStr, OsString};
 
 macro_rules! trait_item {
     ($(#[$md:meta])* get = $getter:ident, item = $item:literal $(, see = $see:path)?) => {
@@ -26,7 +27,7 @@
         #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_get_item")]
         #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_item")]
         #[doc = stdlinks!(3 pam_get_item)]
-        fn $getter(&self) -> Result<Option<String>>;
+        fn $getter(&self) -> Result<Option<OsString>>;
     };
     ($(#[$md:meta])* set = $setter:ident, item = $item:literal $(, see = $see:path)?) => {
         $(#[$md])*
@@ -37,8 +38,10 @@
         )?
         ///
         /// Sets the item's value. PAM copies the string's contents.
-        /// If the string contains a null byte, this will return
-        /// a `ConversationError`.
+        ///
+        /// # Panics
+        ///
+        /// If the string contains a nul byte, this will panic.
         ///
         /// # References
         ///
@@ -47,7 +50,7 @@
         #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_set_item")]
         #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_set_item")]
         #[doc = stdlinks!(3 pam_set_item)]
-        fn $setter(&mut self, value: Option<&str>) -> Result<()>;
+        fn $setter(&mut self, value: Option<&OsStr>) -> Result<()>;
     };
 }
 
@@ -116,13 +119,13 @@
     /// // Get the username using a custom prompt.
     /// // If this were actually called right after the above,
     /// // both user and user_2 would have the same value.
-    /// let user_2 = handle.username(Some("who ARE you even???"))?;
+    /// let user_2 = handle.username(Some("who ARE you even???".as_ref()))?;
     /// # Ok(())
     /// # }
     /// ```
     #[doc = stdlinks!(3 pam_get_user)]
     #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_user")]
-    fn username(&mut self, prompt: Option<&str>) -> Result<String>;
+    fn username(&mut self, prompt: Option<&OsStr>) -> Result<OsString>;
 
     /// The contents of the environment to set, read-only.
     fn environ(&self) -> impl EnvironMap;
@@ -331,18 +334,18 @@
     /// // Get the user's password using the default prompt.
     /// let pass = handle.authtok(None)?;
     /// // Get the user's password using a custom prompt.
-    /// let pass = handle.authtok(Some("Reveal your secrets!"))?;
+    /// let pass = handle.authtok(Some("Reveal your secrets!".as_ref()))?;
     /// Ok(())
     /// # }
     /// ```
     #[doc = man7!(3 pam_get_authtok)]
     #[doc = manbsd!(3 pam_get_authtok)]
-    fn authtok(&mut self, prompt: Option<&str>) -> Result<String>;
+    fn authtok(&mut self, prompt: Option<&OsStr>) -> Result<OsString>;
 
     /// Retrieves the user's old authentication token when changing passwords.
     ///
     ///
-    fn old_authtok(&mut self, prompt: Option<&str>) -> Result<String>;
+    fn old_authtok(&mut self, prompt: Option<&OsStr>) -> Result<OsString>;
 
     trait_item!(
         /// Gets the user's authentication token (e.g., password).