Skip to content

Commit

Permalink
Fix parsing of long host with no scheme (#351)
Browse files Browse the repository at this point in the history
This change fixes an issue where an URI with no scheme, a host
part with a length greater than the max for a scheme, while only
consisting of valid characters for a scheme would fail to parse.

Rather than assuming the string being parsed is meant to contain
a scheme and returning an error if the max length for a scheme is
met, we instead extract the scheme part if it exists and validate
its length.

The trade-off is worse performance in the error case of a scheme
that is too long.
  • Loading branch information
avitex authored and seanmonstar committed Nov 26, 2019
1 parent 8ffe094 commit d3cae7c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
8 changes: 4 additions & 4 deletions src/uri/scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 336,6 @@ impl Scheme2<usize> {
for i in 0..s.len() {
let b = s[i];

if i == MAX_SCHEME_LEN {
return Err(ErrorKind::SchemeTooLong.into());
}

match SCHEME_CHARS[b as usize] {
b':' => {
// Not enough data remaining
Expand All @@ -352,6 348,10 @@ impl Scheme2<usize> {
break;
}

if i > MAX_SCHEME_LEN {
return Err(ErrorKind::SchemeTooLong.into());
}

// Return scheme
return Ok(Scheme2::Other(i));
}
Expand Down
38 changes: 37 additions & 1 deletion src/uri/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 231,30 @@ test_parse! {
port_part = None,
}

test_parse! {
test_uri_parse_long_host_with_no_scheme,
"thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost",
[],

scheme_part = None,
authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost"),
path = "",
query = None,
port_part = None,
}

test_parse! {
test_uri_parse_long_host_with_port_and_no_scheme,
"thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234",
[],

scheme_part = None,
authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234"),
path = "",
query = None,
port_part = Port::from_str("1234").ok(),
}

test_parse! {
test_userinfo1,
"http://a:[email protected]:1234/",
Expand Down Expand Up @@ -430,7 454,7 @@ fn test_max_uri_len() {
}

#[test]
fn test_long_scheme() {
fn test_overflowing_scheme() {
let mut uri = vec![];
uri.extend(vec![b'a'; 256]);
uri.extend(b"://localhost/");
Expand All @@ -441,6 465,18 @@ fn test_long_scheme() {
assert_eq!(res.unwrap_err().0, ErrorKind::SchemeTooLong);
}

#[test]
fn test_max_length_scheme() {
let mut uri = vec![];
uri.extend(vec![b'a'; 64]);
uri.extend(b"://localhost/");

let uri = String::from_utf8(uri).unwrap();
let uri: Uri = uri.parse().unwrap();

assert_eq!(uri.scheme_str().unwrap().len(), 64);
}

#[test]
fn test_uri_to_path_and_query() {
let cases = vec![
Expand Down

0 comments on commit d3cae7c

Please sign in to comment.