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:
		
							
								
								
									
										35
									
								
								src/uri.rs
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/uri.rs
									
									
									
									
									
								
							| @@ -69,18 +69,21 @@ impl Uri { | |||||||
|         } else if s.contains("://") { |         } else if s.contains("://") { | ||||||
|             let url = try!(Url::parse(s)); |             let url = try!(Url::parse(s)); | ||||||
|             let query_len = url.query().unwrap_or("").len(); |             let query_len = url.query().unwrap_or("").len(); | ||||||
|             let v: Vec<&str> = s.split("://").collect(); |             let new_s = url.to_string(); | ||||||
|             let authority_end = v.last().unwrap() |             let authority_end = { | ||||||
|  |                 let v: Vec<&str> = new_s.split("://").collect(); | ||||||
|  |                 v.last().unwrap() | ||||||
|                         .split(url.path()) |                         .split(url.path()) | ||||||
|                         .next() |                         .next() | ||||||
|                                         .unwrap_or(s) |                         .unwrap_or(&new_s) | ||||||
|                                         .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 }; |                         .len() + if v.len() == 2 { v[0].len() + 3 } else { 0 } | ||||||
|  |             }; | ||||||
|             let fragment_len = url.fragment().unwrap_or("").len(); |             let fragment_len = url.fragment().unwrap_or("").len(); | ||||||
|             match url.origin() { |             match url.origin() { | ||||||
|                 url::Origin::Opaque(_) => Err(Error::Method), |                 url::Origin::Opaque(_) => Err(Error::Method), | ||||||
|                 url::Origin::Tuple(scheme, _, _) => { |                 url::Origin::Tuple(scheme, _, _) => { | ||||||
|                     Ok(Uri { |                     Ok(Uri { | ||||||
|                         source: url.to_string().into(), |                         source: new_s.into(), | ||||||
|                         scheme_end: Some(scheme.len()), |                         scheme_end: Some(scheme.len()), | ||||||
|                         authority_end: if authority_end > 0 { Some(authority_end) } else { None }, |                         authority_end: if authority_end > 0 { Some(authority_end) } else { None }, | ||||||
|                         query: if query_len > 0 { Some(query_len) } else { None }, |                         query: if query_len > 0 { Some(query_len) } else { None }, | ||||||
| @@ -297,6 +300,28 @@ test_parse! { | |||||||
|     fragment = None, |     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] | #[test] | ||||||
| fn test_uri_parse_error() { | fn test_uri_parse_error() { | ||||||
|     fn err(s: &str) { |     fn err(s: &str) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user