LibWeb: Support cookie Max-Age attributes that exceed i64 limits

Attributes have a max value length of 1024. So we theoretically need to
support values in the range -${"9".repeat(1023)} to ${"9".repeat(1024)}.
These obviously do not fit in an i64, so we were previously failing to
parse the attribute.

We will now cap the parsed value to the numeric limits of an i64, after
ensuring that the attribute value is indeed a number.
This commit is contained in:
Timothy Flynn 2024-09-18 12:10:47 -04:00 committed by Tim Ledbetter
parent 47e9357243
commit ba1189cd1c
Notes: github-actions[bot] 2024-09-18 23:03:04 +00:00
3 changed files with 18 additions and 9 deletions
Tests/LibWeb/Text
Userland/Libraries/LibWeb/Cookie

View file

@ -14,9 +14,9 @@ Public suffix: ""
SameSite=Lax: "cookie=value"
SameSite=Strict: "cookie=value"
SameSite=None: ""
Max-Age (before expiration): "cookie-max-age=value"
Expires (before expiration): "cookie-expires=value; cookie-max-age=value"
Max-Age (after expiration): ""
Max-Age (before expiration): "cookie-max-age1=value; cookie-max-age2=value"
Expires (before expiration): "cookie-expires=value; cookie-max-age1=value; cookie-max-age2=value"
Max-Age (after expiration): "cookie-max-age2=value"
Expires (after expiration): ""
Max-Age in past: ""
Expires in past: ""

View file

@ -113,16 +113,19 @@
};
const maxAgeTest1 = () => {
document.cookie = "cookie-max-age=value; max-age=1";
document.cookie = "cookie-max-age1=value; max-age=1";
document.cookie = `cookie-max-age2=value; max-age=${"1".repeat(1024)}`;
printCookies("Max-Age (before expiration)");
};
const maxAgeTest2 = () => {
printCookies("Max-Age (after expiration)");
deleteCookie("cookie-max-age2");
};
const maxAgeInPastTest = () => {
document.cookie = "cookie=value; max-age=-1";
document.cookie = "cookie1=value; max-age=-1";
document.cookie = `cookie2=value; max-age=-${"1".repeat(1023)}`;
printCookies("Max-Age in past");
};

View file

@ -226,14 +226,20 @@ void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_valu
// 2. If the first character of the attribute-value is neither a DIGIT, nor a "-" character followed by a DIGIT,
// ignore the cookie-av.
if (!is_ascii_digit(attribute_value[0]) && attribute_value[0] != '-')
// 3. If the remainder of attribute-value contains a non-DIGIT character, ignore the cookie-av.
auto digits = attribute_value[0] == '-' ? attribute_value.substring_view(1) : attribute_value;
if (digits.is_empty() || !all_of(digits, is_ascii_digit))
return;
// 3. If the remainder of attribute-value contains a non-DIGIT character, ignore the cookie-av.
// 4. Let delta-seconds be the attribute-value converted to a base 10 integer.
auto delta_seconds = attribute_value.to_number<i64>();
if (!delta_seconds.has_value())
return;
if (!delta_seconds.has_value()) {
// We know the attribute value only contains digits, so if we failed to parse, it is because the result did not
// fit in an i64. Set the value to the i64 limits in that case. The positive limit will be further capped below,
// and the negative limit will be immediately expired in the cookie jar.
delta_seconds = attribute_value[0] == '-' ? NumericLimits<i64>::min() : NumericLimits<i64>::max();
}
// 5. Let cookie-age-limit be the maximum age of the cookie (which SHOULD be 400 days or less, see Section 5.5).
auto cookie_age_limit = maximum_cookie_age();