diff --git a/Cargo.toml b/Cargo.toml index 416c2f56e..b4fb8805d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "url" -version = "1.2.2" +version = "1.2.3" authors = ["The rust-url developers"] description = "URL library for Rust, based on the WHATWG URL Standard" diff --git a/src/host.rs b/src/host.rs index 47b049a27..84da2c2fa 100644 --- a/src/host.rs +++ b/src/host.rs @@ -371,23 +371,33 @@ fn parse_ipv6addr(input: &str) -> ParseResult { } let mut dots_seen = 0; while i < len { - // FIXME: https://github.com/whatwg/url/commit/1c22aa119c354e0020117e02571cec53f7c01064 - let mut value = 0u16; + let mut value = None; while i < len { let digit = match input[i] { c @ b'0' ... b'9' => c - b'0', _ => break }; - value = value * 10 + digit as u16; - if value == 0 || value > 255 { - return Err(ParseError::InvalidIpv6Address) + match value { + None => value = Some(digit as u16), + Some(0) => return Err(ParseError::InvalidIpv6Address), // No leading zero + Some(ref mut v) => { + *v = *v * 10 + digit as u16; + if *v > 255 { + return Err(ParseError::InvalidIpv6Address) + } + } } + i += 1; } if dots_seen < 3 && !(i < len && input[i] == b'.') { return Err(ParseError::InvalidIpv6Address) } - pieces[piece_pointer] = pieces[piece_pointer] * 0x100 + value; - if dots_seen == 0 || dots_seen == 2 { + pieces[piece_pointer] = if let Some(v) = value { + pieces[piece_pointer] * 0x100 + v + } else { + return Err(ParseError::InvalidIpv6Address) + }; + if dots_seen == 1 || dots_seen == 3 { piece_pointer += 1; } i += 1; diff --git a/src/lib.rs b/src/lib.rs index f8be5e16b..513bd448b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -314,7 +314,10 @@ impl Url { match self.host { HostInternal::None => assert_eq!(host_str, ""), HostInternal::Ipv4(address) => assert_eq!(host_str, address.to_string()), - HostInternal::Ipv6(address) => assert_eq!(host_str, format!("[{}]", address)), + HostInternal::Ipv6(address) => { + let h: Host = Host::Ipv6(address); + assert_eq!(host_str, h.to_string()) + } HostInternal::Domain => { if SchemeType::from(self.scheme()).is_special() { assert!(!host_str.is_empty()) diff --git a/tests/urltestdata.json b/tests/urltestdata.json index ee5416ecf..fca7d7b70 100644 --- a/tests/urltestdata.json +++ b/tests/urltestdata.json @@ -840,6 +840,36 @@ "search": "", "hash": "" }, + { + "input": "http://[::127.0.0.1]", + "base": "http://example.org/foo/bar", + "href": "http://[::7f00:1]/", + "origin": "http://[::7f00:1]", + "protocol": "http:", + "username": "", + "password": "", + "host": "[::7f00:1]", + "hostname": "[::7f00:1]", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, + { + "input": "http://[0:0:0:0:0:0:13.1.68.3]", + "base": "http://example.org/foo/bar", + "href": "http://[::d01:4403]/", + "origin": "http://[::d01:4403]", + "protocol": "http:", + "username": "", + "password": "", + "host": "[::d01:4403]", + "hostname": "[::d01:4403]", + "port": "", + "pathname": "/", + "search": "", + "hash": "" + }, { "input": "http://[2001::1]:80", "base": "http://example.org/foo/bar",