diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index df7f475b2d80..f8f51f3c103c 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -165,7 +165,10 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-host fn SetHost(&self, value: USVString) -> ErrorResult { self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetHost); + // Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !self.get_url().cannot_be_a_base() { + self.set_url_component(value, UrlHelper::SetHost); + } Ok(()) } @@ -184,7 +187,10 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-hostname fn SetHostname(&self, value: USVString) -> ErrorResult { self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetHostname); + // Step 4: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !self.get_url().cannot_be_a_base() { + self.set_url_component(value, UrlHelper::SetHostname); + } Ok(()) } @@ -216,7 +222,10 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-pathname fn SetPathname(&self, value: USVString) -> ErrorResult { self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetPathname); + // Step 3: If copyURL's cannot-be-a-base-URL flag is set, terminate these steps. + if !self.get_url().cannot_be_a_base() { + self.set_url_component(value, UrlHelper::SetPathname); + } Ok(()) } @@ -229,7 +238,12 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-port fn SetPort(&self, value: USVString) -> ErrorResult { self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetPort); + let url = self.get_url(); + // Step 4: If copyURL cannot have a username/password/port, then return. + // https://url.spec.whatwg.org/#cannot-have-a-username-password-port + if url.has_host() && !url.cannot_be_a_base() && url.scheme() != "file" { + self.set_url_component(value, UrlHelper::SetPort); + } Ok(()) } @@ -242,9 +256,16 @@ impl LocationMethods for Location { // https://html.spec.whatwg.org/multipage/#dom-location-protocol fn SetProtocol(&self, value: USVString) -> ErrorResult { self.check_same_origin_domain()?; - self.set_url_component(value, UrlHelper::SetProtocol); - Ok(()) - } + // Step 6: If copyURL's scheme is not an HTTP(S) scheme, then terminate these steps. + if let Ok(scheme) = value.split(':').next() { + if scheme.eq_ignore_ascii_case("http") || scheme.eq_ignore_ascii_case("https") { + self.set_url_component(value, UrlHelper::SetProtocol); + } + Ok(()) + } else { + Err(Error::Syntax) + } + } // https://html.spec.whatwg.org/multipage/#dom-location-search fn GetSearch(&self) -> Fallible { diff --git a/components/url/lib.rs b/components/url/lib.rs index 411d3e94683e..497b3fdbefda 100644 --- a/components/url/lib.rs +++ b/components/url/lib.rs @@ -93,6 +93,10 @@ impl ServoUrl { self.0.scheme() } + pub fn has_host(&self) -> bool { + self.0.has_host() + } + pub fn is_secure_scheme(&self) -> bool { let scheme = self.scheme(); scheme == "https" || scheme == "wss" diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini deleted file mode 100644 index a30c51097ab4..000000000000 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken-weird.html.ini +++ /dev/null @@ -1,16 +0,0 @@ -[location-protocol-setter-non-broken-weird.html] - [Set location.protocol to data] - expected: FAIL - - [Set location.protocol to ftp] - expected: FAIL - - [Set location.protocol to gopher] - expected: FAIL - - [Set location.protocol to x] - expected: FAIL - - [Set location.protocol to http+x] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini index ced665416699..c482f46f011d 100644 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini @@ -3,18 +3,5 @@ [Set data URL frame location.protocol to gopher] expected: FAIL - [Set HTTP URL frame location.protocol to gopher] + [Set data URL frame location.protocol to http+x] expected: FAIL - - [Set HTTP URL frame location.protocol to data] - expected: FAIL - - [Set HTTP URL frame location.protocol to x] - expected: FAIL - - [Set HTTP URL frame location.protocol to http+x] - expected: FAIL - - [Set HTTP URL frame location.protocol to ftp] - expected: FAIL -