Fix cookiestore defaults propagation (#42418)

Also fixes propagating expiry clamping to underlying cookie object. This
matters when attempting to inspect expiry time from a retrieved cookie.
According to the WPT tests, setting max-age in a cookie string is
supposed to be visible in the retrieved expiry.


Testing: cookiestore WPT tests cover this behavior

Signed-off-by: Sebastian C <sebsebmc@gmail.com>
This commit is contained in:
Sebastian C
2026-02-07 01:10:01 -06:00
committed by GitHub
parent 60fc5c3e52
commit 639fccd03f
5 changed files with 31 additions and 36 deletions

View File

@@ -86,11 +86,14 @@ impl ServoCookie {
// The user agent MUST limit the maximum value of the Max-Age attribute.
// The limit SHOULD NOT be greater than 400 days (34560000 seconds) in the future.
let clamped_max_age = max_age.min(Duration::seconds(34560000));
let clamped_max_age = max_age.min(Duration::seconds(34_560_000));
// 2. Set the cookie's expiry-time to attribute-value of the last
// attribute in the cookie-attribute-list with an attribute-name of "Max-Age".
expiry_time = Some(SystemTime::now() + clamped_max_age);
cookie.set_max_age(clamped_max_age);
// cookie-rs doesn't seem to mirror the max-age value to expiry and vice versa so we do explicitly
cookie.set_expires(Some(OffsetDateTime::now_utc() + clamped_max_age));
}
// Otherwise, if the cookie-attribute-list contains an attribute with an attribute-name of "Expires":
else if let Some(date_time) = cookie.expires_datetime() {
@@ -100,11 +103,14 @@ impl ServoCookie {
// The user agent MUST limit the maximum value of the Expires attribute.
// The limit SHOULD NOT be greater than 400 days (34560000 seconds) in the future.
let clamped_date_time =
date_time.min(OffsetDateTime::now_utc() + Duration::seconds(34560000));
date_time.min(OffsetDateTime::now_utc() + Duration::seconds(34_560_000));
// 2. Set the cookie's expiry-time to attribute-value of the last attribute in the
// cookie-attribute-list with an attribute-name of "Expires".
expiry_time = Some(clamped_date_time.into());
cookie.set_expires(Some(clamped_date_time));
// cookie-rs doesn't seem to mirror the max-age value to expiry and vice versa so we do explicitly
cookie.set_max_age(Some(clamped_date_time - OffsetDateTime::now_utc()));
}
// Otherwise:
else {

View File

@@ -17,8 +17,10 @@ use itertools::Itertools;
use js::jsval::NullValue;
use net_traits::CookieSource::NonHTTP;
use net_traits::{CookieAsyncResponse, CookieData, CoreResourceMsg};
use script_bindings::codegen::GenericBindings::CookieStoreBinding::CookieSameSite;
use script_bindings::script_runtime::CanGc;
use servo_url::ServoUrl;
use time::OffsetDateTime;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CookieStoreBinding::{
@@ -493,10 +495,26 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
// 6.1. Let r be the result of running set a cookie with url, options["name"], options["value"],
// options["expires"], options["domain"], options["path"], options["sameSite"], and options["partitioned"].
let cookie = Cookie::build((
let mut cookie = Cookie::build((
Cow::Owned(options.name.to_string()),
Cow::Owned(options.value.to_string()),
));
))
.path(options.path.0.clone())
.secure(true)
.http_only(false)
.same_site(match options.sameSite {
CookieSameSite::Lax => SameSite::Lax,
CookieSameSite::Strict => SameSite::Strict,
CookieSameSite::None => SameSite::None,
});
if let Some(domain) = &options.domain {
cookie.inner_mut().set_domain(domain.0.clone());
}
if let Some(expiry) = options.expires {
cookie.inner_mut().set_expires(
OffsetDateTime::from_unix_timestamp((*expiry / 1000.0) as i64).unwrap(),
);
}
// TODO: This currently doesn't implement all the "set a cookie" steps which involves
// additional processing of the name and value

View File

@@ -1,6 +1,7 @@
[change_eventhandler_for_already_expired.https.window.html]
expected: TIMEOUT
[CookieStore setting already-expired cookie should not be observed]
expected: FAIL
expected: TIMEOUT
[CookieStore setting already-expired partitioned cookie should not be observed]
expected: FAIL
expected: NOTRUN

View File

@@ -1,24 +0,0 @@
[cookieListItem_attributes.https.window.html]
[CookieListItem - cookieStore.set defaults with name and value in options]
expected: FAIL
[CookieListItem - cookieStore.set with expires set to a timestamp 10 years in the future]
expected: FAIL
[CookieListItem - cookieStore.set with expires set to a Date 10 years in the future]
expected: FAIL
[CookieListItem - cookieStore.set with path set to the current directory]
expected: FAIL
[CookieListItem - cookieStore.set with sameSite set to strict]
expected: FAIL
[CookieListItem - cookieStore.set with sameSite set to lax]
expected: FAIL
[CookieListItem - cookieStore.set with sameSite set to none]
expected: FAIL
[Test max-age attribute over the 400 days]
expected: FAIL

View File

@@ -1,9 +1,3 @@
[cookieStore_get_set_across_origins.sub.https.html]
[cookieStore.get() sees cookieStore.set() in cross-origin frame]
expected: FAIL
[cookieStore.get() in cross-origin frame sees cookieStore.set()]
expected: FAIL
[__Host- cookies set via cookieStore.set() in same-site domains don't overwrite each other]
expected: FAIL