From cd62b212b40d34a201d7efe1de36240b415ce978 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 18 Jun 2018 15:18:02 -0700 Subject: [PATCH] Authority::parse should reject mulitple port sections (#215) --- src/uri/authority.rs | 17 +++++++++++++++++ src/uri/tests.rs | 29 ++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/uri/authority.rs b/src/uri/authority.rs index 1fd7870..6232947 100644 --- a/src/uri/authority.rs +++ b/src/uri/authority.rs @@ -87,6 +87,7 @@ impl Authority { // Note: this may return an *empty* Authority. You might want `parse_non_empty`. pub(super) fn parse(s: &[u8]) -> Result { + let mut colon_cnt = 0; let mut start_bracket = false; let mut end_bracket = false; let mut end = s.len(); @@ -97,11 +98,22 @@ impl Authority { end = i; break; } + b':' => { + colon_cnt += 1; + }, b'[' => { start_bracket = true; } b']' => { end_bracket = true; + + // Those were part of an IPv6 hostname, so forget them... + colon_cnt = 0; + } + b'@' => { + // Those weren't a port colon, but part of the + // userinfo, so it needs to be forgotten. + colon_cnt = 0; } 0 => { return Err(ErrorKind::InvalidUriChar.into()); @@ -114,6 +126,11 @@ impl Authority { return Err(ErrorKind::InvalidAuthority.into()); } + if colon_cnt > 1 { + // Things like 'localhost:8080:3030' are rejected. + return Err(ErrorKind::InvalidAuthority.into()); + } + Ok(end) } diff --git a/src/uri/tests.rs b/src/uri/tests.rs index 9294b10..17a2273 100644 --- a/src/uri/tests.rs +++ b/src/uri/tests.rs @@ -120,6 +120,7 @@ test_parse! { port = Some(3000), } + test_parse! { test_uri_parse_absolute_with_default_port_http, "http://127.0.0.1:80", @@ -246,6 +247,32 @@ test_parse! { port = None, } +test_parse! { + test_userinfo_with_port, + "user@localhost:3000", + [], + + scheme_part = None, + authority_part = part!("user@localhost:3000"), + path = "", + query = None, + host = Some("localhost"), + port = Some(3000), +} + +test_parse! { + test_userinfo_pass_with_port, + "user:pass@localhost:3000", + [], + + scheme_part = None, + authority_part = part!("user:pass@localhost:3000"), + path = "", + query = None, + host = Some("localhost"), + port = Some(3000), +} + test_parse! { test_ipv6, "http://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]/", @@ -272,7 +299,6 @@ test_parse! { port = None, } - test_parse! { test_ipv6_shorthand2, "http://[::]/", @@ -341,6 +367,7 @@ fn test_uri_parse_error() { err("\0"); err("http://[::1"); err("http://::1]"); + err("localhost:8080:3030"); } #[test]