Skip to content

Commit

Permalink
Handle Ctrl-U in rpassword
Browse files Browse the repository at this point in the history
  • Loading branch information
conradkleinespel committed Oct 20, 2022
1 parent 80929ab commit 77da060
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rpassword"
version = "7.0.0"
version = "7.1.0"
authors = ["Conrad Kleinespel <conradk@conradk.com>"]
description = "Read passwords in console applications."
license = "Apache-2.0"
Expand All @@ -10,6 +10,7 @@ documentation = "https://docs.rs/rpassword/"
readme = "README.md"
keywords = ["read", "password", "security", "pass", "getpass"]
edition = "2018"
rust-version = "1.60"

[features]
serde = ["dep:serde", "dep:serde_json"]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Here's a list of existing `rpassword` contributors:
* [@john-sharratt](https://github.com/john-sharratt)
* [@joshuef](https://github.com/joshuef)
* [@longshorej](https://github.com/longshorej)
* [@LSchallot](https://github.com/LSchallot)
* [@nicokoch](https://github.com/nicokoch)
* [@NovaliX-Dev](https://github.com/NovaliX-Dev)
* [@petevine](https://github.com/petevine)
Expand Down
10 changes: 5 additions & 5 deletions src/rpassword/all.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::rutil::fix_new_line::fix_new_line;
use crate::rutil::fix_line_issues::fix_line_issues;
use crate::rutil::print_tty::{print_tty, print_writer};
use crate::rutil::safe_string::SafeString;
use std::io::{BufRead, Write};
Expand All @@ -22,7 +22,7 @@ mod wasm {
let mut password = super::SafeString::new();

reader.read_line(&mut password)?;
super::fix_new_line(password.into_inner())
super::fix_line_issues(password.into_inner())
}
}

Expand Down Expand Up @@ -104,7 +104,7 @@ mod unix {

std::mem::drop(hidden_input);

super::fix_new_line(password.into_inner())
super::fix_line_issues(password.into_inner())
}
}

Expand Down Expand Up @@ -199,7 +199,7 @@ mod windows {

std::mem::drop(hidden_input);

super::fix_new_line(password.into_inner())
super::fix_line_issues(password.into_inner())
}
}

Expand All @@ -215,7 +215,7 @@ pub fn read_password_from_bufread(reader: &mut impl BufRead) -> std::io::Result<
let mut password = SafeString::new();
reader.read_line(&mut password)?;

fix_new_line(password.into_inner())
fix_line_issues(password.into_inner())
}

/// Prompts on the TTY and then reads a password from anything that implements BufRead
Expand Down
2 changes: 1 addition & 1 deletion src/rutil.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod atty;
pub mod fix_new_line;
pub mod fix_line_issues;
pub mod print_tty;
pub mod safe_string;
#[cfg(feature = "serde")]
Expand Down
10 changes: 9 additions & 1 deletion src/rutil/fix_new_line.rs → src/rutil/fix_line_issues.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// Normalizes the return of `read_line()` in the context of a CLI application
pub fn fix_new_line(mut line: String) -> std::io::Result<String> {
pub fn fix_line_issues(mut line: String) -> std::io::Result<String> {
if !line.ends_with('\n') {
return Err(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,
Expand All @@ -15,5 +15,13 @@ pub fn fix_new_line(mut line: String) -> std::io::Result<String> {
line.pop();
}

// Ctrl-U should remove the line in terminals
if line.contains('') {
line = match line.rfind('') {
Some(last_ctrl_u_index) => line[last_ctrl_u_index + 1..].to_string(),
None => line,
};
}

Ok(line)
}
13 changes: 13 additions & 0 deletions tests/no-terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,16 @@ fn can_read_from_redirected_input_many_times() {
let response = crate::read_password_from_bufread(&mut reader_lf).unwrap();
assert_eq!(response, "Another mocked response.");
}

#[test]
fn can_read_from_input_ctrl_u() {
close_stdin();

let mut reader_ctrl_u = Cursor::new(&b"A mocked response.Another mocked response.\n"[..]);
let response = crate::read_password_from_bufread(&mut reader_ctrl_u).unwrap();
assert_eq!(response, "Another mocked response.");

let mut reader_ctrl_u_at_end = Cursor::new(&b"A mocked response.\n"[..]);
let response = crate::read_password_from_bufread(&mut reader_ctrl_u_at_end).unwrap();
assert_eq!(response, "");
}

0 comments on commit 77da060

Please sign in to comment.