Skip to content

Commit

Permalink
Fix destination username & password parsing to accept full character set
Browse files Browse the repository at this point in the history
  • Loading branch information
chipsenkbeil committed Jun 19, 2023
1 parent 7c08495 commit 9096a7d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- `Request` and `Response` types from `distant-net` now support an optional
`Header` to send miscellaneous information
- New feature `tracing` provides https://github.com/tokio-rs/tracing support
as a new `--tracing` flag. Must be compiled with
`RUSTFLAGS="--cfg tokio_unstable"` to properly operate.

### Changed

Expand All @@ -31,6 +28,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
synchronous as opposed to asynchronous to avoid deadlocks and also be more
performant

### Fixed

- Username and password now support full character sets outside of `@` for
passwords and `:` and `@` for usernames

## [0.20.0-alpha.8]

### Added
Expand Down
62 changes: 47 additions & 15 deletions distant-net/src/common/destination/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,8 @@ fn parse_scheme(s: &str) -> PResult<&str> {

fn parse_username_password(s: &str) -> PResult<(Option<&str>, Option<&str>)> {
let (auth, remaining) = s.split_once('@').ok_or("Auth missing @")?;
let (auth, username) = maybe(parse_until(|c| !c.is_alphanumeric() && c != '-'))(auth)?;
let (auth, password) = maybe(prefixed(
parse_char(':'),
parse_until(|c| !c.is_alphanumeric()),
))(auth)?;
let (auth, username) = maybe(parse_until(|c| c == ':'))(auth)?;
let (auth, password) = maybe(prefixed(parse_char(':'), |s| Ok(("", s))))(auth)?;

if !auth.is_empty() {
return Err("Dangling characters after username/password");
Expand Down Expand Up @@ -297,16 +294,6 @@ mod tests {
let _ = parse_username_password("username:password").unwrap_err();
}

#[test]
fn should_fail_if_username_not_alphanumeric() {
let _ = parse_username_password("us\x1bername:password@").unwrap_err();
}

#[test]
fn should_fail_if_password_not_alphanumeric() {
let _ = parse_username_password("username:pas\x1bsword@").unwrap_err();
}

#[test]
fn should_return_username_if_available() {
let (s, username_password) = parse_username_password("username@").unwrap();
Expand Down Expand Up @@ -349,13 +336,58 @@ mod tests {
assert_eq!(username_password.1, Some("password"));
}

#[test]
fn should_support_username_with_backslash() {
let (s, username_password) = parse_username_password(r#"orgname\myname@"#).unwrap();
assert_eq!(s, "");
assert_eq!(username_password.0, Some(r#"orgname\myname"#));
assert_eq!(username_password.1, None);

let (s, username_password) =
parse_username_password(r#"orgname\myname:password@"#).unwrap();
assert_eq!(s, "");
assert_eq!(username_password.0, Some(r#"orgname\myname"#));
assert_eq!(username_password.1, Some("password"));
}

#[test]
fn should_support_username_and_password_with_arbitrary_characters() {
let (s, username_password) =
parse_username_password("name1!#$%^&*()[]{{}}\x1b:pass1!#$%^&*()[]{{}}\x1b@")
.unwrap();
assert_eq!(s, "");
assert_eq!(username_password.0, Some("name1!#$%^&*()[]{{}}\x1b"));
assert_eq!(username_password.1, Some("pass1!#$%^&*()[]{{}}\x1b"));
}

#[test]
fn should_support_colons_in_password() {
let (s, username_password) =
parse_username_password("user:name:password@").unwrap();
assert_eq!(s, "");
assert_eq!(username_password.0, Some("user"));
assert_eq!(username_password.1, Some("name:password"));
}

#[test]
fn should_consume_up_to_the_ending_sequence() {
let (s, username_password) =
parse_username_password("username:[email protected]").unwrap();
assert_eq!(s, "example.com");
assert_eq!(username_password.0, Some("username"));
assert_eq!(username_password.1, Some("password"));

let (s, username_password) =
parse_username_password("user@name:password@").unwrap();
assert_eq!(s, "name:password@");
assert_eq!(username_password.0, Some("user"));
assert_eq!(username_password.1, None);

let (s, username_password) =
parse_username_password("username:pass@word@").unwrap();
assert_eq!(s, "word@");
assert_eq!(username_password.0, Some("username"));
assert_eq!(username_password.1, Some("pass"));
}
}

Expand Down

0 comments on commit 9096a7d

Please sign in to comment.