mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-27 04:37:22 +00:00
LibWeb+LibURL: Default empty string paths to URL's path in CookieStore
This commit is contained in:
parent
2f61199b01
commit
1f1adb6d7e
Notes:
github-actions[bot]
2025-08-17 20:18:38 +00:00
Author: https://github.com/IdanHo
Commit: 1f1adb6d7e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5876
Reviewed-by: https://github.com/gmta ✅
3 changed files with 59 additions and 26 deletions
|
@ -85,6 +85,11 @@ void URL::set_paths(Vector<ByteString> const& paths)
|
||||||
m_data->paths.unchecked_append(percent_encode(segment, PercentEncodeSet::Path));
|
m_data->paths.unchecked_append(percent_encode(segment, PercentEncodeSet::Path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void URL::set_raw_paths(Vector<String> paths)
|
||||||
|
{
|
||||||
|
m_data->paths = move(paths);
|
||||||
|
}
|
||||||
|
|
||||||
void URL::append_path(StringView path)
|
void URL::append_path(StringView path)
|
||||||
{
|
{
|
||||||
m_data->paths.append(percent_encode(path, PercentEncodeSet::Path));
|
m_data->paths.append(percent_encode(path, PercentEncodeSet::Path));
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
void set_host(Host);
|
void set_host(Host);
|
||||||
void set_port(Optional<u16>);
|
void set_port(Optional<u16>);
|
||||||
void set_paths(Vector<ByteString> const&);
|
void set_paths(Vector<ByteString> const&);
|
||||||
|
void set_raw_paths(Vector<String>);
|
||||||
Vector<String> const& paths() const { return m_data->paths; }
|
Vector<String> const& paths() const { return m_data->paths; }
|
||||||
void set_query(Optional<String> query) { m_data->query = move(query); }
|
void set_query(Optional<String> query) { m_data->query = move(query); }
|
||||||
void set_fragment(Optional<String> fragment) { m_data->fragment = move(fragment); }
|
void set_fragment(Optional<String> fragment) { m_data->fragment = move(fragment); }
|
||||||
|
|
|
@ -327,11 +327,42 @@ GC::Ref<WebIDL::Promise> CookieStore::get_all(CookieStoreGetOptions const& optio
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-layered-cookies#name-cookie-default-path
|
||||||
|
static Vector<String> cookie_default_path(Vector<String> path)
|
||||||
|
{
|
||||||
|
// 1. Assert: path is a non-empty list.
|
||||||
|
VERIFY(!path.is_empty());
|
||||||
|
|
||||||
|
// 2. If path's size is greater than 1, then remove path's last item.
|
||||||
|
if (path.size() > 1)
|
||||||
|
path.take_last();
|
||||||
|
|
||||||
|
// 3. Otherwise, set path[0] to the empty string.
|
||||||
|
else
|
||||||
|
path[0] = ""_string;
|
||||||
|
|
||||||
|
// 4. Return path.
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://fetch.spec.whatwg.org/#serialized-cookie-default-path
|
||||||
|
static String serialized_cookie_default_path(URL::URL const& url)
|
||||||
|
{
|
||||||
|
// 1. Let cloneURL be a clone of url.
|
||||||
|
auto clone_url = url;
|
||||||
|
|
||||||
|
// 2. Set cloneURL’s path to the cookie default path of cloneURL’s path.
|
||||||
|
clone_url.set_raw_paths(cookie_default_path(clone_url.paths()));
|
||||||
|
|
||||||
|
// 3. Return the URL path serialization of cloneURL.
|
||||||
|
return clone_url.serialize_path();
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr size_t maximum_name_value_pair_size = 4096;
|
static constexpr size_t maximum_name_value_pair_size = 4096;
|
||||||
static constexpr size_t maximum_attribute_value_size = 1024;
|
static constexpr size_t maximum_attribute_value_size = 1024;
|
||||||
|
|
||||||
// https://cookiestore.spec.whatwg.org/#set-a-cookie
|
// https://cookiestore.spec.whatwg.org/#set-a-cookie
|
||||||
static bool set_a_cookie(PageClient& client, URL::URL const& url, String name, String value, Optional<HighResolutionTime::DOMHighResTimeStamp> expires, Optional<String> const& domain, Optional<String> const& path, Bindings::CookieSameSite same_site, bool partitioned)
|
static bool set_a_cookie(PageClient& client, URL::URL const& url, String name, String value, Optional<HighResolutionTime::DOMHighResTimeStamp> expires, Optional<String> const& domain, String path, Bindings::CookieSameSite same_site, bool partitioned)
|
||||||
{
|
{
|
||||||
// 1. Normalize name.
|
// 1. Normalize name.
|
||||||
name = normalize(name);
|
name = normalize(name);
|
||||||
|
@ -427,34 +458,30 @@ static bool set_a_cookie(PageClient& client, URL::URL const& url, String name, S
|
||||||
if (expires.has_value())
|
if (expires.has_value())
|
||||||
parsed_cookie.expiry_time_from_expires_attribute = UnixDateTime::from_milliseconds_since_epoch(expires.value());
|
parsed_cookie.expiry_time_from_expires_attribute = UnixDateTime::from_milliseconds_since_epoch(expires.value());
|
||||||
|
|
||||||
// 14. If path is not null:
|
// 14. If path is the empty string, then set path to the serialized cookie default path of url.
|
||||||
if (path.has_value()) {
|
if (path.is_empty())
|
||||||
// 1. If path does not start with U+002F (/), then return failure.
|
path = serialized_cookie_default_path(url);
|
||||||
if (!path->starts_with('/'))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// 2. If path is not U+002F (/), and name, byte-lowercased, starts with `__host-`, then return failure.
|
// 15. If path does not start with U+002F (/), then return failure.
|
||||||
if (path != "/"sv && name_byte_lowercased.starts_with_bytes("__host-"sv))
|
if (!path.starts_with('/'))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// 3. Let encodedPath be the result of UTF-8 encoding path.
|
// 16. If path is not U+002F (/), and name, byte-lowercased, starts with `__host-`, then return failure.
|
||||||
|
if (path != "/"sv && name_byte_lowercased.starts_with_bytes("__host-"sv))
|
||||||
|
return false;
|
||||||
|
|
||||||
// 4. If the byte sequence length of encodedPath is greater than the maximum attribute value size, then return failure.
|
// 17. Let encodedPath be the result of UTF-8 encoding path.
|
||||||
if (path->byte_count() > maximum_attribute_value_size)
|
// 18. If the byte sequence length of encodedPath is greater than the maximum attribute value size, then return failure.
|
||||||
return false;
|
if (path.byte_count() > maximum_attribute_value_size)
|
||||||
|
return false;
|
||||||
|
|
||||||
// 5. Append `Path`/encodedPath to attributes.
|
// 19. Append `Path`/encodedPath to attributes.
|
||||||
parsed_cookie.path = path;
|
parsed_cookie.path = path;
|
||||||
}
|
|
||||||
// 15. Otherwise, append `Path`/ U+002F (/) to attributes.
|
|
||||||
else {
|
|
||||||
parsed_cookie.path = "/"_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 16. Append `Secure`/`` to attributes.
|
// 20. Append `Secure`/`` to attributes.
|
||||||
parsed_cookie.secure_attribute_present = true;
|
parsed_cookie.secure_attribute_present = true;
|
||||||
|
|
||||||
// 17. Switch on sameSite:
|
// 21. Switch on sameSite:
|
||||||
switch (same_site) {
|
switch (same_site) {
|
||||||
// -> "none"
|
// -> "none"
|
||||||
case Bindings::CookieSameSite::None:
|
case Bindings::CookieSameSite::None:
|
||||||
|
@ -473,15 +500,15 @@ static bool set_a_cookie(PageClient& client, URL::URL const& url, String name, S
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 18. If partitioned is true, Append `Partitioned`/`` to attributes.
|
// FIXME: 22. If partitioned is true, Append `Partitioned`/`` to attributes.
|
||||||
(void)partitioned;
|
(void)partitioned;
|
||||||
|
|
||||||
// 19. Perform the steps defined in Cookies § Storage Model for when the user agent "receives a cookie" with url as
|
// 23. Perform the steps defined in Cookies § Storage Model for when the user agent "receives a cookie" with url as
|
||||||
// request-uri, encodedName as cookie-name, encodedValue as cookie-value, and attributes as cookie-attribute-list.
|
// request-uri, encodedName as cookie-name, encodedValue as cookie-value, and attributes as cookie-attribute-list.
|
||||||
// For the purposes of the steps, the newly-created cookie was received from a "non-HTTP" API.
|
// For the purposes of the steps, the newly-created cookie was received from a "non-HTTP" API.
|
||||||
client.page_did_set_cookie(url, parsed_cookie, Cookie::Source::NonHttp);
|
client.page_did_set_cookie(url, parsed_cookie, Cookie::Source::NonHttp);
|
||||||
|
|
||||||
// 20. Return success.
|
// 24. Return success.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,7 +605,7 @@ GC::Ref<WebIDL::Promise> CookieStore::set(CookieInit const& options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://cookiestore.spec.whatwg.org/#delete-a-cookie
|
// https://cookiestore.spec.whatwg.org/#delete-a-cookie
|
||||||
static bool delete_a_cookie(PageClient& client, URL::URL const& url, String name, Optional<String> domain, Optional<String> path, bool partitioned)
|
static bool delete_a_cookie(PageClient& client, URL::URL const& url, String name, Optional<String> domain, String path, bool partitioned)
|
||||||
{
|
{
|
||||||
// 1. Let expires be the earliest representable date represented as a timestamp.
|
// 1. Let expires be the earliest representable date represented as a timestamp.
|
||||||
// NOTE: The exact value of expires is not important for the purposes of this algorithm, as long as it is in the past.
|
// NOTE: The exact value of expires is not important for the purposes of this algorithm, as long as it is in the past.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue