LibWeb+LibURL: Use URL paths directly for comparison

This matches the text of the spec a little more closely in many cases
and is also more efficient than serializing the URL path.
This commit is contained in:
Shannon Booth 2024-08-05 15:14:00 +12:00 committed by Andreas Kling
commit ffe070d7f9
Notes: github-actions[bot] 2024-08-05 07:59:07 +00:00
5 changed files with 9 additions and 11 deletions

View file

@ -150,6 +150,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&);
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); }
void set_cannot_be_a_base_url(bool value) { m_data->cannot_be_a_base_url = value; } void set_cannot_be_a_base_url(bool value) { m_data->cannot_be_a_base_url = value; }

View file

@ -799,7 +799,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<PendingResponse>> scheme_fetch(JS::Realm& r
// a body. // a body.
// NOTE: URLs such as "about:config" are handled during navigation and result in a network error in the context // NOTE: URLs such as "about:config" are handled during navigation and result in a network error in the context
// of fetching. // of fetching.
if (request->current_url().serialize_path() == "blank"sv) { if (request->current_url().paths().size() == 1 && request->current_url().paths()[0] == "blank"sv) {
auto response = Infrastructure::Response::create(vm); auto response = Infrastructure::Response::create(vm);
response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes()))); response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes())));

View file

@ -310,7 +310,8 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::construct_impl(JS::Realm
// - parsedReferrers origin is not same origin with origin // - parsedReferrers origin is not same origin with origin
// then set requests referrer to "client". // then set requests referrer to "client".
auto parsed_referrer_origin = DOMURL::url_origin(parsed_referrer); auto parsed_referrer_origin = DOMURL::url_origin(parsed_referrer);
if ((parsed_referrer.scheme() == "about"sv && parsed_referrer.serialize_path() == "client"sv) || !parsed_referrer_origin.is_same_origin(origin)) { if ((parsed_referrer.scheme() == "about"sv && parsed_referrer.paths().size() == 1 && parsed_referrer.paths()[0] == "client"sv)
|| !parsed_referrer_origin.is_same_origin(origin)) {
request->set_referrer(Infrastructure::Request::Referrer::Client); request->set_referrer(Infrastructure::Request::Referrer::Client);
} }
// 4. Otherwise, set requests referrer to parsedReferrer. // 4. Otherwise, set requests referrer to parsedReferrer.

View file

@ -40,7 +40,7 @@ bool url_matches_about_blank(URL::URL const& url)
{ {
// A URL matches about:blank if its scheme is "about", its path contains a single string "blank", its username and password are the empty string, and its host is null. // A URL matches about:blank if its scheme is "about", its path contains a single string "blank", its username and password are the empty string, and its host is null.
return url.scheme() == "about"sv return url.scheme() == "about"sv
&& url.serialize_path() == "blank"sv && url.paths().size() == 1 && url.paths()[0] == "blank"sv
&& url.username().is_empty() && url.username().is_empty()
&& url.password().is_empty() && url.password().is_empty()
&& url.host().has<Empty>(); && url.host().has<Empty>();
@ -51,7 +51,7 @@ bool url_matches_about_srcdoc(URL::URL const& url)
{ {
// A URL matches about:srcdoc if its scheme is "about", its path contains a single string "srcdoc", its query is null, its username and password are the empty string, and its host is null. // A URL matches about:srcdoc if its scheme is "about", its path contains a single string "srcdoc", its query is null, its username and password are the empty string, and its host is null.
return url.scheme() == "about"sv return url.scheme() == "about"sv
&& url.serialize_path() == "srcdoc"sv && url.paths().size() == 1 && url.paths()[0] == "srcdoc"sv
&& !url.query().has_value() && !url.query().has_value()
&& url.username().is_empty() && url.username().is_empty()
&& url.password().is_empty() && url.password().is_empty()

View file

@ -148,17 +148,13 @@ bool can_have_its_url_rewritten(DOM::Document const& document, URL::URL const& t
// 4. If targetURL's scheme is "file", and targetURL and documentURL differ in their path component, // 4. If targetURL's scheme is "file", and targetURL and documentURL differ in their path component,
// then return false. (Differences in query and fragment are allowed for file: URLs.) // then return false. (Differences in query and fragment are allowed for file: URLs.)
// FIXME: Don't create temporary strings to compare paths bool path_components_match = target_url.paths() == document_url.paths();
auto target_url_path = target_url.serialize_path(); if (target_url.scheme() == "file"sv && !path_components_match)
auto document_url_path = document_url.serialize_path();
if (target_url.scheme() == "file"sv
&& target_url_path != document_url_path)
return false; return false;
// 5. If targetURL and documentURL differ in their path component or query components, then return false. // 5. If targetURL and documentURL differ in their path component or query components, then return false.
// (Only differences in fragment are allowed for other types of URLs.) // (Only differences in fragment are allowed for other types of URLs.)
if (target_url_path != document_url_path if (!path_components_match || target_url.query() != document_url.query())
|| target_url.query() != document_url.query())
return false; return false;
// 6. Return true. // 6. Return true.