fix(uri): fix panic when uri contain default port

Parsing "http://host:80" caused panic (index out of bound) because the
authority end index was computed with the original uri but the uri
stored for later used was sanitized by `Url::parse()` to "http://host"

The fix computes the autority end index with the actual uri used (the
one from `Url::parse()`). Two tests have been added.
This commit is contained in:
Florent Monjalet
2017-01-20 17:17:33 +01:00
parent f45e9c8e4f
commit 594ea65420

View File

@@ -69,18 +69,21 @@ impl Uri {
} else if s.contains("://") {
let url = try!(Url::parse(s));
let query_len = url.query().unwrap_or("").len();
let v: Vec<&str> = s.split("://").collect();
let authority_end = v.last().unwrap()
.split(url.path())
.next()
.unwrap_or(s)
.len() + if v.len() == 2 { v[0].len() + 3 } else { 0 };
let new_s = url.to_string();
let authority_end = {
let v: Vec<&str> = new_s.split("://").collect();
v.last().unwrap()
.split(url.path())
.next()
.unwrap_or(&new_s)
.len() + if v.len() == 2 { v[0].len() + 3 } else { 0 }
};
let fragment_len = url.fragment().unwrap_or("").len();
match url.origin() {
url::Origin::Opaque(_) => Err(Error::Method),
url::Origin::Tuple(scheme, _, _) => {
Ok(Uri {
source: url.to_string().into(),
source: new_s.into(),
scheme_end: Some(scheme.len()),
authority_end: if authority_end > 0 { Some(authority_end) } else { None },
query: if query_len > 0 { Some(query_len) } else { None },
@@ -297,6 +300,28 @@ test_parse! {
fragment = None,
}
test_parse! {
test_uri_parse_absolute_with_default_port_http,
"http://127.0.0.1:80",
scheme = Some("http"),
authority = Some("127.0.0.1"),
path = "/",
query = None,
fragment = None,
}
test_parse! {
test_uri_parse_absolute_with_default_port_https,
"https://127.0.0.1:443",
scheme = Some("https"),
authority = Some("127.0.0.1"),
path = "/",
query = None,
fragment = None,
}
#[test]
fn test_uri_parse_error() {
fn err(s: &str) {