diff src/conv.rs @ 93:efc2b56c8928

Remove undefined behavior per MIRI. This replaces a bunch of raw pointers with NonNull and removes all the undefined behavior that we can find with MIRI. We also remove the `SecureString` dependency (since it doesn't work with MIRI, and because it's not really necessary).
author Paul Fisher <paul@pfish.zone>
date Mon, 23 Jun 2025 13:02:58 -0400
parents 05291b601f0a
children db167f96ba46
line wrap: on
line diff
--- a/src/conv.rs	Sun Jun 22 19:29:32 2025 -0400
+++ b/src/conv.rs	Mon Jun 23 13:02:58 2025 -0400
@@ -4,9 +4,9 @@
 #![allow(dead_code)]
 
 use crate::constants::{ErrorCode, Result};
-use secure_string::SecureString;
 use std::cell::Cell;
 use std::fmt;
+use std::fmt::Debug;
 use std::result::Result as StdResult;
 
 /// The types of message and request that can be sent to a user.
@@ -122,7 +122,7 @@
     /// A Q&A that asks the user for text and does not show it while typing.
     ///
     /// In other words, a password entry prompt.
-    MaskedQAndA<'a, Q=&'a str, A=SecureString>,
+    MaskedQAndA<'a, Q=&'a str, A=String>,
     Message::MaskedPrompt
 );
 
@@ -284,11 +284,10 @@
 ///
 /// ```
 /// # use nonstick::{Conversation, Result};
-/// # use secure_string::SecureString;
 /// // Bring this trait into scope to get `masked_prompt`, among others.
 /// use nonstick::SimpleConversation;
 ///
-/// fn ask_for_token(convo: &mut impl Conversation) -> Result<SecureString> {
+/// fn ask_for_token(convo: &mut impl Conversation) -> Result<String> {
 ///     convo.masked_prompt("enter your one-time token")
 /// }
 /// ```
@@ -297,7 +296,6 @@
 ///
 /// ```
 /// use nonstick::{Conversation, SimpleConversation};
-/// use secure_string::SecureString;
 /// # use nonstick::{BinaryData, Result};
 /// mod some_library {
 /// #    use nonstick::Conversation;
@@ -314,7 +312,7 @@
 /// #     todo!()
 /// # }
 /// #
-/// # fn masked_prompt(&mut self, request: &str) -> Result<SecureString> {
+/// # fn masked_prompt(&mut self, request: &str) -> Result<String> {
 /// #     todo!()
 /// # }
 /// #
@@ -355,7 +353,7 @@
     /// Prompts the user for something.
     fn prompt(&mut self, request: &str) -> Result<String>;
     /// Prompts the user for something, but hides what the user types.
-    fn masked_prompt(&mut self, request: &str) -> Result<SecureString>;
+    fn masked_prompt(&mut self, request: &str) -> Result<String>;
     /// Alerts the user to an error.
     fn error_msg(&mut self, message: &str);
     /// Sends an informational message to the user.
@@ -403,7 +401,7 @@
 
 impl<C: Conversation> SimpleConversation for C {
     conv_fn!(prompt(message: &str) -> String { QAndA });
-    conv_fn!(masked_prompt(message: &str) -> SecureString { MaskedQAndA } );
+    conv_fn!(masked_prompt(message: &str) -> String { MaskedQAndA } );
     conv_fn!(error_msg(message: &str) { ErrorMsg });
     conv_fn!(info_msg(message: &str) { InfoMsg });
     conv_fn!(radio_prompt(message: &str) -> String { RadioQAndA });
@@ -464,9 +462,9 @@
                     _ => panic!("unexpected prompt!"),
                 }
             }
-            fn masked_prompt(&mut self, request: &str) -> Result<SecureString> {
+            fn masked_prompt(&mut self, request: &str) -> Result<String> {
                 assert_eq!("reveal", request);
-                Ok(SecureString::from("my secrets"))
+                Ok("my secrets".to_owned())
             }
             fn error_msg(&mut self, message: &str) {
                 self.error_ran = true;
@@ -507,7 +505,7 @@
         ]);
 
         assert_eq!("whatwhat", what.answer().unwrap());
-        assert_eq!(SecureString::from("my secrets"), pass.answer().unwrap());
+        assert_eq!("my secrets", pass.answer().unwrap());
         assert_eq!(Ok(()), err.answer());
         assert_eq!(Ok(()), info.answer());
         assert_eq!(ErrorCode::PermissionDenied, has_err.answer().unwrap_err());
@@ -572,10 +570,7 @@
         let mut tester = MuxTester;
 
         assert_eq!("answer", tester.prompt("question").unwrap());
-        assert_eq!(
-            SecureString::from("open sesame"),
-            tester.masked_prompt("password!").unwrap()
-        );
+        assert_eq!("open sesame", tester.masked_prompt("password!").unwrap());
         tester.error_msg("oh no");
         tester.info_msg("let me tell you");
         // Linux-PAM extensions. Always implemented, but separate for clarity.