From dd224a3ce9e052da53d5b9003d162c2a4416d177 Mon Sep 17 00:00:00 2001 From: Jeremy Lempereur Date: Sat, 20 Jul 2019 19:50:37 +0200 Subject: [PATCH 1/4] Try to update the port on scheme change. --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index cd6bdf326..5b8daa6aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1954,6 +1954,13 @@ impl Url { parser.serialization.push_str(self.slice(old_scheme_end..)); self.serialization = parser.serialization; + + // Update the port so it can be removed + // If it is the scheme's default + // We don't mind it silently failing + // If there was no port in the first place + let _ = self.set_port(self.port()); + Ok(()) } From 27f713485adfbb6ed8ce41e86f1d80117867153c Mon Sep 17 00:00:00 2001 From: Jeremy Lempereur Date: Sat, 20 Jul 2019 23:31:39 +0200 Subject: [PATCH 2/4] Applied the host parsing rules to the setter. --- src/lib.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5b8daa6aa..5d752e558 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1569,10 +1569,25 @@ impl Url { if host == "" && SchemeType::from(self.scheme()).is_special() { return Err(ParseError::EmptyHost); } + let mut host_substr = host; + // Otherwise, if c is U+003A (:) and the [] flag is unset, then + if !host.starts_with('[') || !host.ends_with(']') { + match host.find(':') { + Some(0) => { + // If buffer is the empty string, validation error, return failure. + return Err(ParseError::InvalidDomainCharacter); + } + // Let host be the result of host parsing buffer + Some(colon_index) => { + host_substr = &host[..colon_index]; + } + None => {} + } + } if SchemeType::from(self.scheme()).is_special() { - self.set_host_internal(Host::parse(host)?, None) + self.set_host_internal(Host::parse(host_substr)?, None); } else { - self.set_host_internal(Host::parse_opaque(host)?, None) + self.set_host_internal(Host::parse_opaque(host_substr)?, None); } } else if self.has_host() { if SchemeType::from(self.scheme()).is_special() { From 9641d45050dc458b7c86d836ea8a05d0baaae6a1 Mon Sep 17 00:00:00 2001 From: Jeremy Lempereur Date: Sun, 21 Jul 2019 00:19:35 +0200 Subject: [PATCH 3/4] Hash getter and setter. --- src/quirks.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/quirks.rs b/src/quirks.rs index 285ee21b6..6b8594735 100644 --- a/src/quirks.rs +++ b/src/quirks.rs @@ -208,13 +208,14 @@ pub fn hash(url: &Url) -> &str { /// Setter for https://url.spec.whatwg.org/#dom-url-hash pub fn set_hash(url: &mut Url, new_hash: &str) { - if url.scheme() != "javascript" { - url.set_fragment(match new_hash { - "" => None, - _ if new_hash.starts_with('#') => Some(&new_hash[1..]), - _ => Some(new_hash), - }) - } + url.set_fragment(match new_hash { + // If the given value is the empty string, + // then set context object’s url’s fragment to null and return. + "" => None, + // Let input be the given value with a single leading U+0023 (#) removed, if any. + _ if new_hash.starts_with('#') => Some(&new_hash[1..]), + _ => Some(new_hash), + }) } fn trim(s: &str) -> &str { From 08f0d48e0ca58fa5054a8464d49a299e0eff1346 Mon Sep 17 00:00:00 2001 From: Jeremy Lempereur Date: Sun, 21 Jul 2019 16:06:41 +0200 Subject: [PATCH 4/4] Do not try to set port if empty string. --- src/quirks.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/quirks.rs b/src/quirks.rs index 6b8594735..8684bed6f 100644 --- a/src/quirks.rs +++ b/src/quirks.rs @@ -111,9 +111,13 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> { Ok((h, remaining)) => { host = h; opt_port = if let Some(remaining) = remaining.split_prefix(':') { - Parser::parse_port(remaining, || default_port(scheme), Context::Setter) - .ok() - .map(|(port, _remaining)| port) + if remaining.is_empty() { + None + } else { + Parser::parse_port(remaining, || default_port(scheme), Context::Setter) + .ok() + .map(|(port, _remaining)| port) + } } else { None };