diff options
Diffstat (limited to 'src/pinentry.rs')
-rw-r--r-- | src/pinentry.rs | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/pinentry.rs b/src/pinentry.rs index b4d2bb0..e2a83ed 100644 --- a/src/pinentry.rs +++ b/src/pinentry.rs @@ -1,5 +1,6 @@ use crate::prelude::*; +use std::convert::TryFrom as _; use tokio::io::AsyncWriteExt as _; pub async fn getpin( @@ -33,18 +34,18 @@ pub async fn getpin( .map_err(|source| Error::WriteStdin { source })?; ncommands += 1; stdin - .write_all(format!("SETPROMPT {}\n", prompt).as_bytes()) + .write_all(format!("SETPROMPT {prompt}\n").as_bytes()) .await .map_err(|source| Error::WriteStdin { source })?; ncommands += 1; stdin - .write_all(format!("SETDESC {}\n", desc).as_bytes()) + .write_all(format!("SETDESC {desc}\n").as_bytes()) .await .map_err(|source| Error::WriteStdin { source })?; ncommands += 1; if let Some(err) = err { stdin - .write_all(format!("SETERROR {}\n", err).as_bytes()) + .write_all(format!("SETERROR {err}\n").as_bytes()) .await .map_err(|source| Error::WriteStdin { source })?; ncommands += 1; @@ -76,15 +77,13 @@ pub async fn getpin( Ok(crate::locked::Password::new(buf)) } -async fn read_password< - R: tokio::io::AsyncRead + tokio::io::AsyncReadExt + Unpin, ->( +async fn read_password<R>( mut ncommands: u8, data: &mut [u8], mut r: R, ) -> Result<usize> where - R: Send, + R: tokio::io::AsyncRead + tokio::io::AsyncReadExt + Unpin + Send, { let mut len = 0; loop { @@ -119,7 +118,7 @@ where }); } return Err(Error::PinentryErrorMessage { - error: format!("unknown error ({})", code), + error: format!("unknown error ({code})"), }); } None => { @@ -138,6 +137,14 @@ where .read(&mut data[len..]) .await .map_err(|source| Error::PinentryReadOutput { source })?; + if bytes == 0 { + return Err(Error::PinentryReadOutput { + source: std::io::Error::new( + std::io::ErrorKind::UnexpectedEof, + "unexpected EOF", + ), + }); + } len += bytes; } } @@ -161,9 +168,11 @@ fn percent_decode(buf: &mut [u8]) -> usize { if c == b'%' && read_idx + 2 < len { if let Some(h) = char::from(buf[read_idx + 1]).to_digit(16) { - #[allow(clippy::cast_possible_truncation)] if let Some(l) = char::from(buf[read_idx + 2]).to_digit(16) { - c = h as u8 * 0x10 + l as u8; + // h and l were parsed from a single hex digit, so they + // must be in the range 0-15, so these unwraps are safe + c = u8::try_from(h).unwrap() * 0x10 + + u8::try_from(l).unwrap(); read_idx += 2; } } |