mirror of
https://github.com/servo/servo.git
synced 2025-09-10 15:08:21 +01:00
script: Do not include fragments when comparing URLs in CookieStore
(#38876)
Fixes a check for empty options in `getAll(options)` and makes url comparison with exclude fragments set to true. Testing: New passing WPT tests Part of #37674 --------- Signed-off-by: Sebastian C <sebsebmc@gmail.com>
This commit is contained in:
parent
84f478a47a
commit
e5c83ec419
14 changed files with 46 additions and 66 deletions
|
@ -259,12 +259,12 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
// 6.1. Let parsed be the result of parsing options["url"] with settings’s API base URL.
|
// 6.1. Let parsed be the result of parsing options["url"] with settings’s API base URL.
|
||||||
let parsed_url = ServoUrl::parse_with_base(Some(&global.api_base_url()), get_url);
|
let parsed_url = ServoUrl::parse_with_base(Some(&global.api_base_url()), get_url);
|
||||||
|
|
||||||
// 6.2. If this’s relevant global object is a Window object and parsed does not equal url,
|
// 6.2. If this’s relevant global object is a Window object and parsed does not equal url with exclude fragments set to true,
|
||||||
// then return a promise rejected with a TypeError.
|
// then return a promise rejected with a TypeError.
|
||||||
if let Some(_window) = DomRoot::downcast::<Window>(self.global()) {
|
if let Some(_window) = DomRoot::downcast::<Window>(self.global()) {
|
||||||
if parsed_url
|
if parsed_url
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_ok_and(|parsed| parsed.as_url() != creation_url.as_url())
|
.is_ok_and(|parsed| !parsed.is_equal_excluding_fragments(creation_url))
|
||||||
{
|
{
|
||||||
p.reject_error(
|
p.reject_error(
|
||||||
Error::Type("URL does not match context".to_string()),
|
Error::Type("URL does not match context".to_string()),
|
||||||
|
@ -354,7 +354,7 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
// 2. Let origin be settings’s origin.
|
// 2. Let origin be settings’s origin.
|
||||||
let origin = global.origin();
|
let origin = global.origin();
|
||||||
|
|
||||||
// 7. Let p be a new promise.
|
// 6. Let p be a new promise.
|
||||||
let p = Promise::new(&global, can_gc);
|
let p = Promise::new(&global, can_gc);
|
||||||
|
|
||||||
// 3. If origin is an opaque origin, then return a promise rejected with a "SecurityError" DOMException.
|
// 3. If origin is an opaque origin, then return a promise rejected with a "SecurityError" DOMException.
|
||||||
|
@ -366,26 +366,19 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
// 4. Let url be settings’s creation URL.
|
// 4. Let url be settings’s creation URL.
|
||||||
let creation_url = global.creation_url();
|
let creation_url = global.creation_url();
|
||||||
|
|
||||||
// 5. If options is empty, then return a promise rejected with a TypeError.
|
|
||||||
// "is empty" is not strictly defined anywhere in the spec but the only value we require here is "url"
|
|
||||||
if options.url.is_none() && options.name.is_none() {
|
|
||||||
p.reject_error(Error::Type("Options cannot be empty".to_string()), can_gc);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut final_url = creation_url.clone();
|
let mut final_url = creation_url.clone();
|
||||||
|
|
||||||
// 6. If options["url"] is present, then run these steps:
|
// 5. If options["url"] is present, then run these steps:
|
||||||
if let Some(get_url) = &options.url {
|
if let Some(get_url) = &options.url {
|
||||||
// 6.1. Let parsed be the result of parsing options["url"] with settings’s API base URL.
|
// 5.1. Let parsed be the result of parsing options["url"] with settings’s API base URL.
|
||||||
let parsed_url = ServoUrl::parse_with_base(Some(&global.api_base_url()), get_url);
|
let parsed_url = ServoUrl::parse_with_base(Some(&global.api_base_url()), get_url);
|
||||||
|
|
||||||
// 6.2. If this’s relevant global object is a Window object and parsed does not equal url,
|
// If this’s relevant global object is a Window object and parsed does not equal url with exclude fragments set to true,
|
||||||
// then return a promise rejected with a TypeError.
|
// then return a promise rejected with a TypeError.
|
||||||
if let Some(_window) = DomRoot::downcast::<Window>(self.global()) {
|
if let Some(_window) = DomRoot::downcast::<Window>(self.global()) {
|
||||||
if parsed_url
|
if parsed_url
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_ok_and(|parsed| parsed.as_url() != creation_url.as_url())
|
.is_ok_and(|parsed| !parsed.is_equal_excluding_fragments(creation_url))
|
||||||
{
|
{
|
||||||
p.reject_error(
|
p.reject_error(
|
||||||
Error::Type("URL does not match context".to_string()),
|
Error::Type("URL does not match context".to_string()),
|
||||||
|
@ -395,7 +388,7 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.3. If parsed’s origin and url’s origin are not the same origin,
|
// 5.3. If parsed’s origin and url’s origin are not the same origin,
|
||||||
// then return a promise rejected with a TypeError.
|
// then return a promise rejected with a TypeError.
|
||||||
if parsed_url
|
if parsed_url
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -405,13 +398,13 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.4. Set url to parsed.
|
// 5.4. Set url to parsed.
|
||||||
if let Ok(url) = parsed_url {
|
if let Ok(url) = parsed_url {
|
||||||
final_url = url;
|
final_url = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Run the following steps in parallel:
|
// 7. Run the following steps in parallel:
|
||||||
let res =
|
let res =
|
||||||
self.global()
|
self.global()
|
||||||
.resource_threads()
|
.resource_threads()
|
||||||
|
|
|
@ -117,6 +117,13 @@ impl ServoUrl {
|
||||||
scheme == "wss"
|
scheme == "wss"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://url.spec.whatwg.org/#url-equivalence>
|
||||||
|
/// In the future this may be removed if the helper is added upstream in rust-url
|
||||||
|
/// see <https://github.com/servo/rust-url/issues/1063> for details
|
||||||
|
pub fn is_equal_excluding_fragments(&self, other: &ServoUrl) -> bool {
|
||||||
|
self.0[..Position::AfterQuery] == other.0[..Position::AfterQuery]
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
self.0.as_str()
|
self.0.as_str()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
[change_eventhandler_for_document_cookie.https.window.html]
|
[change_eventhandler_for_document_cookie.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[document.cookie set/overwrite/delete observed by CookieStore]
|
[document.cookie set/overwrite/delete observed by CookieStore]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[document.cookie set already-expired cookie should not be observed by CookieStore]
|
[document.cookie set already-expired cookie should not be observed by CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[document.cookie duplicate cookie should not be observed by CookieStore]
|
[document.cookie duplicate cookie should not be observed by CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[CookieStore set/overwrite/delete observed by document.cookie]
|
[CookieStore set/overwrite/delete observed by document.cookie]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[CookieStore agrees with document.cookie on encoding non-ASCII cookies]
|
[CookieStore agrees with document.cookie on encoding non-ASCII cookies]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[document.cookie agrees with CookieStore on encoding non-ASCII cookies]
|
[document.cookie agrees with CookieStore on encoding non-ASCII cookies]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
[change_eventhandler_for_http_cookie_and_set_cookie_headers.https.window.html]
|
[change_eventhandler_for_http_cookie_and_set_cookie_headers.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[HTTP set/overwrite/delete observed in CookieStore]
|
[HTTP set/overwrite/delete observed in CookieStore]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[HTTP set already-expired cookie should not be observed by CookieStore]
|
[HTTP set already-expired cookie should not be observed by CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[HTTP duplicate cookie should not be observed by CookieStore]
|
[HTTP duplicate cookie should not be observed by CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[CookieStore agreed with HTTP headers agree on encoding non-ASCII cookies]
|
[CookieStore agreed with HTTP headers agree on encoding non-ASCII cookies]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[CookieStore set/overwrite/delete observed in HTTP headers]
|
[CookieStore set/overwrite/delete observed in HTTP headers]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[HTTP headers agreed with CookieStore on encoding non-ASCII cookies]
|
[HTTP headers agreed with CookieStore on encoding non-ASCII cookies]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[Binary HTTP set/overwrite/delete observed in CookieStore]
|
[Binary HTTP set/overwrite/delete observed in CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[change_eventhandler_for_no_change.https.window.html]
|
[change_eventhandler_for_no_change.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[CookieStore duplicate cookie should not be observed]
|
[CookieStore duplicate cookie should not be observed]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[CookieStore duplicate partitioned cookie should not be observed]
|
[CookieStore duplicate partitioned cookie should not be observed]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[change_eventhandler_for_no_name_and_no_value.https.window.html]
|
[change_eventhandler_for_no_name_and_no_value.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Verify behavior of no-name and no-value cookies.]
|
[Verify behavior of no-name and no-value cookies.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[change_eventhandler_for_no_name_equals_in_value.https.window.html]
|
[change_eventhandler_for_no_name_equals_in_value.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Verify that attempting to set a cookie with no name and with '=' in the value does not work.]
|
[Verify that attempting to set a cookie with no name and with '=' in the value does not work.]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
[change_eventhandler_for_no_name_multiple_values.https.window.html]
|
[change_eventhandler_for_no_name_multiple_values.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Verify behavior of multiple no-name cookies]
|
[Verify behavior of multiple no-name cookies]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -2,17 +2,5 @@
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
||||||
[cookieStore_getAll_arguments.https.any.html]
|
[cookieStore_getAll_arguments.https.any.html]
|
||||||
[cookieStore.getAll with no arguments]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.getAll with empty options]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.getAll with absolute url with fragment in options]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.getAll with absolute different url in options]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.getAll with whitespace]
|
[cookieStore.getAll with whitespace]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
[cookieStore_getAll_multiple.https.any.html]
|
[cookieStore_getAll_multiple.https.any.html]
|
||||||
[cookieStore.getAll returns multiple cookies written by cookieStore.set]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
||||||
[cookieStore_getAll_multiple.https.any.serviceworker.html]
|
[cookieStore_getAll_multiple.https.any.serviceworker.html]
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
[cookieStore_getAll_set_creation_url.https.any.html]
|
|
||||||
[cookieStore.set and cookieStore.getAll use the creation url]
|
|
||||||
expected: FAIL
|
|
|
@ -2,11 +2,5 @@
|
||||||
expected: ERROR
|
expected: ERROR
|
||||||
|
|
||||||
[cookieStore_get_arguments.https.any.html]
|
[cookieStore_get_arguments.https.any.html]
|
||||||
[cookieStore.get with absolute url with fragment in options]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.get with absolute different url in options]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore.get with whitespace]
|
[cookieStore.get with whitespace]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
[cookieStore_opaque_origin.https.html]
|
[cookieStore_opaque_origin.https.html]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
[cookieStore in non-sandboxed iframe should not throw]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[cookieStore in sandboxed iframe should throw SecurityError]
|
[cookieStore in sandboxed iframe should throw SecurityError]
|
||||||
expected: TIMEOUT
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
[httponly_cookies.https.window.html]
|
[httponly_cookies.https.window.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[HttpOnly cookies are not observed]
|
[HttpOnly cookies are not observed]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[HttpOnly cookies can not be set by document.cookie]
|
[HttpOnly cookies can not be set by document.cookie]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[HttpOnly cookies can not be set by CookieStore]
|
[HttpOnly cookies can not be set by CookieStore]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[HttpOnly cookies are not deleted/overwritten]
|
[HttpOnly cookies are not deleted/overwritten]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue