diff options
-rw-r--r-- | Userland/Applications/Browser/CookieJar.cpp | 40 | ||||
-rw-r--r-- | Userland/Applications/Browser/CookiesModel.cpp | 2 | ||||
-rw-r--r-- | Userland/Applications/Browser/StorageWidget.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Cookie/Cookie.cpp | 29 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Cookie/Cookie.h | 14 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp | 26 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Cookie/ParsedCookie.h | 8 | ||||
-rw-r--r-- | Userland/Services/WebContent/WebDriverConnection.cpp | 9 |
8 files changed, 83 insertions, 47 deletions
diff --git a/Userland/Applications/Browser/CookieJar.cpp b/Userland/Applications/Browser/CookieJar.cpp index 2e39fce90d..76d987f8f8 100644 --- a/Userland/Applications/Browser/CookieJar.cpp +++ b/Userland/Applications/Browser/CookieJar.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Tim Flynn <trflynn89@serenityos.org> + * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org> * Copyright (c) 2022, the SerenityOS developers. * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> * @@ -11,6 +11,7 @@ #include <AK/IPv4Address.h> #include <AK/StringBuilder.h> #include <AK/StringView.h> +#include <AK/Time.h> #include <AK/URL.h> #include <AK/Vector.h> #include <LibCore/Promise.h> @@ -140,9 +141,9 @@ void CookieJar::dump_cookies() builder.appendff("{}{}{}\n", key_color, cookie.path, no_color); builder.appendff("\t{}Value{} = {}\n", attribute_color, no_color, cookie.value); - builder.appendff("\t{}CreationTime{} = {}\n", attribute_color, no_color, cookie.creation_time.to_deprecated_string()); - builder.appendff("\t{}LastAccessTime{} = {}\n", attribute_color, no_color, cookie.last_access_time.to_deprecated_string()); - builder.appendff("\t{}ExpiryTime{} = {}\n", attribute_color, no_color, cookie.expiry_time.to_deprecated_string()); + builder.appendff("\t{}CreationTime{} = {}\n", attribute_color, no_color, cookie.creation_time_to_string()); + builder.appendff("\t{}LastAccessTime{} = {}\n", attribute_color, no_color, cookie.last_access_time_to_string()); + builder.appendff("\t{}ExpiryTime{} = {}\n", attribute_color, no_color, cookie.expiry_time_to_string()); builder.appendff("\t{}Secure{} = {:s}\n", attribute_color, no_color, cookie.secure); builder.appendff("\t{}HttpOnly{} = {:s}\n", attribute_color, no_color, cookie.http_only); builder.appendff("\t{}HostOnly{} = {:s}\n", attribute_color, no_color, cookie.host_only); @@ -275,7 +276,7 @@ void CookieJar::store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, con // 2. Create a new cookie with name cookie-name, value cookie-value. Set the creation-time and the last-access-time to the current date and time. Web::Cookie::Cookie cookie { parsed_cookie.name, parsed_cookie.value, parsed_cookie.same_site_attribute }; - cookie.creation_time = Core::DateTime::now(); + cookie.creation_time = Time::now_realtime(); cookie.last_access_time = cookie.creation_time; if (parsed_cookie.expiry_time_from_max_age_attribute.has_value()) { @@ -289,9 +290,9 @@ void CookieJar::store_cookie(Web::Cookie::ParsedCookie const& parsed_cookie, con cookie.persistent = true; cookie.expiry_time = parsed_cookie.expiry_time_from_expires_attribute.value(); } else { - // Set the cookie's persistent-flag to false. Set the cookie's expiry-time to the latest representable gddate. + // Set the cookie's persistent-flag to false. Set the cookie's expiry-time to the latest representable date. cookie.persistent = false; - cookie.expiry_time = Core::DateTime::create(9999, 12, 31, 23, 59, 59); + cookie.expiry_time = Time::max(); } // 4. If the cookie-attribute-list contains an attribute with an attribute-name of "Domain": @@ -396,13 +397,13 @@ Vector<Web::Cookie::Cookie> CookieJar::get_matching_cookies(const URL& url, Depr // - Cookies with longer paths are listed before cookies with shorter paths. // - Among cookies that have equal-length path fields, cookies with earlier creation-times are listed before cookies with later creation-times. auto cookie_path_length = cookie.path.length(); - auto cookie_creation_time = cookie.creation_time.timestamp(); + auto cookie_creation_time = cookie.creation_time; cookie_list.insert_before_matching(move(cookie), [cookie_path_length, cookie_creation_time](auto const& entry) { if (cookie_path_length > entry.path.length()) { return true; } else if (cookie_path_length == entry.path.length()) { - if (cookie_creation_time < entry.creation_time.timestamp()) + if (cookie_creation_time < entry.creation_time) return true; } return false; @@ -410,7 +411,7 @@ Vector<Web::Cookie::Cookie> CookieJar::get_matching_cookies(const URL& url, Depr }); // 3. Update the last-access-time of each cookie in the cookie-list to the current date and time. - auto now = Core::DateTime::now(); + auto now = Time::now_realtime(); for (auto& cookie : cookie_list) { cookie.last_access_time = now; @@ -450,8 +451,8 @@ static ErrorOr<Web::Cookie::Cookie> parse_cookie(ReadonlySpan<SQL::Value> row) if (value.type() != SQL::SQLType::Integer) return Error::from_string_view(name); - auto time = value.to_int<time_t>().value(); - field = Core::DateTime::from_timestamp(time); + auto time = value.to_int<i64>().value(); + field = Time::from_seconds(time); return {}; }; @@ -492,9 +493,9 @@ void CookieJar::insert_cookie_into_database(Web::Cookie::Cookie const& cookie) cookie.name, cookie.value, to_underlying(cookie.same_site), - cookie.creation_time.timestamp(), - cookie.last_access_time.timestamp(), - cookie.expiry_time.timestamp(), + cookie.creation_time.to_seconds(), + cookie.last_access_time.to_seconds(), + cookie.expiry_time.to_seconds(), cookie.domain, cookie.path, cookie.secure, @@ -509,9 +510,9 @@ void CookieJar::update_cookie_in_database(Web::Cookie::Cookie const& cookie) m_statements.update_cookie, {}, [this]() { purge_expired_cookies(); }, {}, cookie.value, to_underlying(cookie.same_site), - cookie.creation_time.timestamp(), - cookie.last_access_time.timestamp(), - cookie.expiry_time.timestamp(), + cookie.creation_time.to_seconds(), + cookie.last_access_time.to_seconds(), + cookie.expiry_time.to_seconds(), cookie.secure, cookie.http_only, cookie.host_only, @@ -581,7 +582,8 @@ void CookieJar::select_all_cookies_from_database(OnSelectAllCookiesResult on_res void CookieJar::purge_expired_cookies() { - auto now = Core::DateTime::now().timestamp(); + auto now = Time::now_realtime().to_seconds(); m_database.execute_statement(m_statements.expire_cookie, {}, {}, {}, now); } + } diff --git a/Userland/Applications/Browser/CookiesModel.cpp b/Userland/Applications/Browser/CookiesModel.cpp index 50df78a243..2d16901bd5 100644 --- a/Userland/Applications/Browser/CookiesModel.cpp +++ b/Userland/Applications/Browser/CookiesModel.cpp @@ -80,7 +80,7 @@ GUI::Variant CookiesModel::data(GUI::ModelIndex const& index, GUI::ModelRole rol case Column::Value: return cookie.value; case Column::ExpiryTime: - return cookie.expiry_time.to_deprecated_string(); + return cookie.expiry_time_to_string(); case Column::SameSite: return Web::Cookie::same_site_to_string(cookie.same_site); } diff --git a/Userland/Applications/Browser/StorageWidget.cpp b/Userland/Applications/Browser/StorageWidget.cpp index 4c7314fd87..9837b879cd 100644 --- a/Userland/Applications/Browser/StorageWidget.cpp +++ b/Userland/Applications/Browser/StorageWidget.cpp @@ -130,7 +130,7 @@ void StorageWidget::clear_session_storage_entries() void StorageWidget::delete_cookie(Web::Cookie::Cookie cookie) { // Delete cookie by making its expiry time in the past. - cookie.expiry_time = Core::DateTime::from_timestamp(0); + cookie.expiry_time = Time::from_seconds(0); if (on_update_cookie) on_update_cookie(move(cookie)); } diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp index 229ca38090..bbef4fb5c6 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp @@ -1,15 +1,38 @@ /* * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> + * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include "Cookie.h" +#include <LibCore/DateTime.h> #include <LibIPC/Decoder.h> #include <LibIPC/Encoder.h> namespace Web::Cookie { +static DeprecatedString time_to_string(Time const& time) +{ + auto local_time = Core::DateTime::from_timestamp(time.to_seconds()); + return local_time.to_deprecated_string("%Y-%m-%d %H:%M:%S %Z"sv); +} + +DeprecatedString Cookie::creation_time_to_string() const +{ + return time_to_string(creation_time); +} + +DeprecatedString Cookie::last_access_time_to_string() const +{ + return time_to_string(last_access_time); +} + +DeprecatedString Cookie::expiry_time_to_string() const +{ + return time_to_string(expiry_time); +} + StringView same_site_to_string(SameSite same_site) { switch (same_site) { @@ -64,11 +87,11 @@ ErrorOr<Web::Cookie::Cookie> IPC::decode(Decoder& decoder) auto value = TRY(decoder.decode<DeprecatedString>()); auto domain = TRY(decoder.decode<DeprecatedString>()); auto path = TRY(decoder.decode<DeprecatedString>()); - auto creation_time = TRY(decoder.decode<Core::DateTime>()); - auto expiry_time = TRY(decoder.decode<Core::DateTime>()); + auto creation_time = TRY(decoder.decode<Time>()); + auto expiry_time = TRY(decoder.decode<Time>()); auto host_only = TRY(decoder.decode<bool>()); auto http_only = TRY(decoder.decode<bool>()); - auto last_access_time = TRY(decoder.decode<Core::DateTime>()); + auto last_access_time = TRY(decoder.decode<Time>()); auto persistent = TRY(decoder.decode<bool>()); auto secure = TRY(decoder.decode<bool>()); auto same_site = TRY(decoder.decode<Web::Cookie::SameSite>()); diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.h b/Userland/Libraries/LibWeb/Cookie/Cookie.h index c3b4c9768c..e54d168621 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.h +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> + * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,7 +7,7 @@ #pragma once #include <AK/DeprecatedString.h> -#include <LibCore/DateTime.h> +#include <AK/Time.h> #include <LibIPC/Forward.h> namespace Web::Cookie { @@ -25,12 +25,16 @@ enum class Source { }; struct Cookie { + DeprecatedString creation_time_to_string() const; + DeprecatedString last_access_time_to_string() const; + DeprecatedString expiry_time_to_string() const; + DeprecatedString name; DeprecatedString value; SameSite same_site; - Core::DateTime creation_time {}; - Core::DateTime last_access_time {}; - Core::DateTime expiry_time {}; + Time creation_time {}; + Time last_access_time {}; + Time expiry_time {}; DeprecatedString domain {}; DeprecatedString path {}; bool secure { false }; diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp index e04870f1bb..0d6102b114 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> + * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,6 +8,7 @@ #include <AK/DateConstants.h> #include <AK/Function.h> #include <AK/StdLibExtras.h> +#include <AK/Time.h> #include <AK/Vector.h> #include <LibIPC/Decoder.h> #include <LibIPC/Encoder.h> @@ -26,7 +27,7 @@ static void on_path_attribute(ParsedCookie& parsed_cookie, StringView attribute_ static void on_secure_attribute(ParsedCookie& parsed_cookie); static void on_http_only_attribute(ParsedCookie& parsed_cookie); static void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_value); -static Optional<Core::DateTime> parse_date_time(StringView date_string); +static Optional<Time> parse_date_time(StringView date_string); Optional<ParsedCookie> parse_cookie(DeprecatedString const& cookie_string) { @@ -153,7 +154,7 @@ void on_expires_attribute(ParsedCookie& parsed_cookie, StringView attribute_valu { // https://tools.ietf.org/html/rfc6265#section-5.2.1 if (auto expiry_time = parse_date_time(attribute_value); expiry_time.has_value()) - parsed_cookie.expiry_time_from_expires_attribute = move(*expiry_time); + parsed_cookie.expiry_time_from_expires_attribute = expiry_time.release_value(); } void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_value) @@ -168,11 +169,10 @@ void on_max_age_attribute(ParsedCookie& parsed_cookie, StringView attribute_valu if (auto delta_seconds = attribute_value.to_int(); delta_seconds.has_value()) { if (*delta_seconds <= 0) { // If delta-seconds is less than or equal to zero (0), let expiry-time be the earliest representable date and time. - parsed_cookie.expiry_time_from_max_age_attribute = Core::DateTime::from_timestamp(0); + parsed_cookie.expiry_time_from_max_age_attribute = Time::min(); } else { // Otherwise, let the expiry-time be the current date and time plus delta-seconds seconds. - time_t now = Core::DateTime::now().timestamp(); - parsed_cookie.expiry_time_from_max_age_attribute = Core::DateTime::from_timestamp(now + *delta_seconds); + parsed_cookie.expiry_time_from_max_age_attribute = Time::now_realtime() + Time::from_seconds(*delta_seconds); } } } @@ -236,7 +236,7 @@ void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_va parsed_cookie.same_site_attribute = same_site_from_string(attribute_value); } -Optional<Core::DateTime> parse_date_time(StringView date_string) +Optional<Time> parse_date_time(StringView date_string) { // https://tools.ietf.org/html/rfc6265#section-5.1.1 unsigned hour = 0; @@ -341,8 +341,14 @@ Optional<Core::DateTime> parse_date_time(StringView date_string) if (second > 59) return {}; + // 6. Let the parsed-cookie-date be the date whose day-of-month, month, year, hour, minute, and second (in UTC) are the + // day-of-month-value, the month-value, the year-value, the hour-value, the minute-value, and the second-value, respectively. + // If no such date exists, abort these steps and fail to parse the cookie-date. // FIXME: Fail on dates that do not exist. - return Core::DateTime::create(year, month, day_of_month, hour, minute, second); + auto parsed_cookie_date = Time::from_timestamp(year, month, day_of_month, hour, minute, second, 0); + + // 7. Return the parsed-cookie-date as the result of this algorithm. + return parsed_cookie_date; } } @@ -368,8 +374,8 @@ ErrorOr<Web::Cookie::ParsedCookie> IPC::decode(Decoder& decoder) { auto name = TRY(decoder.decode<DeprecatedString>()); auto value = TRY(decoder.decode<DeprecatedString>()); - auto expiry_time_from_expires_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); - auto expiry_time_from_max_age_attribute = TRY(decoder.decode<Optional<Core::DateTime>>()); + auto expiry_time_from_expires_attribute = TRY(decoder.decode<Optional<Time>>()); + auto expiry_time_from_max_age_attribute = TRY(decoder.decode<Optional<Time>>()); auto domain = TRY(decoder.decode<Optional<DeprecatedString>>()); auto path = TRY(decoder.decode<Optional<DeprecatedString>>()); auto secure_attribute_present = TRY(decoder.decode<bool>()); diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h index 07cc36b292..5779f8d5ee 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org> + * Copyright (c) 2021-2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -8,7 +8,7 @@ #include <AK/DeprecatedString.h> #include <AK/Optional.h> -#include <LibCore/DateTime.h> +#include <AK/Time.h> #include <LibIPC/Forward.h> #include <LibWeb/Cookie/Cookie.h> @@ -18,8 +18,8 @@ struct ParsedCookie { DeprecatedString name; DeprecatedString value; SameSite same_site_attribute { SameSite::Default }; - Optional<Core::DateTime> expiry_time_from_expires_attribute {}; - Optional<Core::DateTime> expiry_time_from_max_age_attribute {}; + Optional<Time> expiry_time_from_expires_attribute {}; + Optional<Time> expiry_time_from_max_age_attribute {}; Optional<DeprecatedString> domain {}; Optional<DeprecatedString> path {}; bool secure_attribute_present { false }; diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index 0361199cad..bc9fcc9514 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -3,13 +3,14 @@ * Copyright (c) 2022-2023, Sam Atkins <atkinssj@serenityos.org> * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org> * Copyright (c) 2022, Linus Groh <linusg@serenityos.org> - * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org> + * Copyright (c) 2022-2023, Tim Flynn <trflynn89@serenityos.org> * * SPDX-License-Identifier: BSD-2-Clause */ #include <AK/JsonObject.h> #include <AK/JsonValue.h> +#include <AK/Time.h> #include <AK/Vector.h> #include <LibJS/Runtime/JSONObject.h> #include <LibJS/Runtime/Value.h> @@ -54,7 +55,7 @@ static JsonValue serialize_cookie(Web::Cookie::Cookie const& cookie) serialized_cookie.set("domain"sv, cookie.domain); serialized_cookie.set("secure"sv, cookie.secure); serialized_cookie.set("httpOnly"sv, cookie.http_only); - serialized_cookie.set("expiry"sv, cookie.expiry_time.timestamp()); + serialized_cookie.set("expiry"sv, cookie.expiry_time.to_seconds()); serialized_cookie.set("sameSite"sv, Web::Cookie::same_site_to_string(cookie.same_site)); return serialized_cookie; @@ -1593,7 +1594,7 @@ Messages::WebDriverClient::AddCookieResponse WebDriverConnection::add_cookie(Jso if (data.has("expiry"sv)) { // NOTE: less than 0 or greater than safe integer are handled by the JSON parser auto expiry = TRY(get_property<u32>(data, "expiry"sv)); - cookie.expiry_time_from_expires_attribute = Core::DateTime::from_timestamp(expiry); + cookie.expiry_time_from_expires_attribute = Time::from_seconds(expiry); } // Cookie same site @@ -1985,7 +1986,7 @@ void WebDriverConnection::delete_cookies(Optional<StringView> const& name) // -> name is equal to cookie name if (!name.has_value() || name.value() == cookie.name) { // Set the cookie expiry time to a Unix timestamp in the past. - cookie.expiry_time = Core::DateTime::from_timestamp(0); + cookie.expiry_time = Time::from_seconds(0); m_page_client.page_did_update_cookie(move(cookie)); } // -> Otherwise |