From ffe070d7f9164ff51644f8d912b580a0b291e26a Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Mon, 5 Aug 2024 15:14:00 +1200 Subject: [PATCH] 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. --- Userland/Libraries/LibURL/URL.h | 1 + Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp | 2 +- Userland/Libraries/LibWeb/Fetch/Request.cpp | 3 ++- Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp | 4 ++-- Userland/Libraries/LibWeb/HTML/History.cpp | 10 +++------- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibURL/URL.h b/Userland/Libraries/LibURL/URL.h index 4193684ca9d..fa4afcd9655 100644 --- a/Userland/Libraries/LibURL/URL.h +++ b/Userland/Libraries/LibURL/URL.h @@ -150,6 +150,7 @@ public: void set_host(Host); void set_port(Optional); void set_paths(Vector const&); + Vector const& paths() const { return m_data->paths; } void set_query(Optional query) { m_data->query = move(query); } void set_fragment(Optional fragment) { m_data->fragment = move(fragment); } void set_cannot_be_a_base_url(bool value) { m_data->cannot_be_a_base_url = value; } diff --git a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp index 4c3105d6688..1ac84ea3d3b 100644 --- a/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Fetching/Fetching.cpp @@ -799,7 +799,7 @@ WebIDL::ExceptionOr> scheme_fetch(JS::Realm& r // a body. // NOTE: URLs such as "about:config" are handled during navigation and result in a network error in the context // 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); response->set_status_message(MUST(ByteBuffer::copy("OK"sv.bytes()))); diff --git a/Userland/Libraries/LibWeb/Fetch/Request.cpp b/Userland/Libraries/LibWeb/Fetch/Request.cpp index ced3ef5c1a5..f46a6abd137 100644 --- a/Userland/Libraries/LibWeb/Fetch/Request.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Request.cpp @@ -310,7 +310,8 @@ WebIDL::ExceptionOr> Request::construct_impl(JS::Realm // - parsedReferrer’s origin is not same origin with origin // then set request’s referrer to "client". 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); } // 4. Otherwise, set request’s referrer to parsedReferrer. diff --git a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp index e834c9b6465..b5caa4378ea 100644 --- a/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp +++ b/Userland/Libraries/LibWeb/HTML/BrowsingContext.cpp @@ -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. return url.scheme() == "about"sv - && url.serialize_path() == "blank"sv + && url.paths().size() == 1 && url.paths()[0] == "blank"sv && url.username().is_empty() && url.password().is_empty() && url.host().has(); @@ -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. return url.scheme() == "about"sv - && url.serialize_path() == "srcdoc"sv + && url.paths().size() == 1 && url.paths()[0] == "srcdoc"sv && !url.query().has_value() && url.username().is_empty() && url.password().is_empty() diff --git a/Userland/Libraries/LibWeb/HTML/History.cpp b/Userland/Libraries/LibWeb/HTML/History.cpp index b9988787667..c3fa2cde3fb 100644 --- a/Userland/Libraries/LibWeb/HTML/History.cpp +++ b/Userland/Libraries/LibWeb/HTML/History.cpp @@ -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, // then return false. (Differences in query and fragment are allowed for file: URLs.) - // FIXME: Don't create temporary strings to compare paths - auto target_url_path = target_url.serialize_path(); - auto document_url_path = document_url.serialize_path(); - if (target_url.scheme() == "file"sv - && target_url_path != document_url_path) + bool path_components_match = target_url.paths() == document_url.paths(); + if (target_url.scheme() == "file"sv && !path_components_match) 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.) - if (target_url_path != document_url_path - || target_url.query() != document_url.query()) + if (!path_components_match || target_url.query() != document_url.query()) return false; // 6. Return true.