From 5acd40c525a695b353dba348a95eb0cb314a33d5 Mon Sep 17 00:00:00 2001 From: MacDue Date: Thu, 13 Apr 2023 23:06:58 +0100 Subject: [PATCH] AK+Everywhere: Add ApplyPercentDecoding option to URL getters The defaults selected for this are based on the behaviour of URL when it applied percent decoding during parsing. This does mean now in some cases the getters will allocate, but percent_decode() checks if there's anything to decode first, so in many cases still won't. --- AK/URL.cpp | 39 ++++++++++++++++++++------- AK/URL.h | 16 ++++++----- Userland/Libraries/LibWeb/URL/URL.cpp | 6 ++--- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/AK/URL.cpp b/AK/URL.cpp index 2346ae22b6..ec045d9292 100644 --- a/AK/URL.cpp +++ b/AK/URL.cpp @@ -47,6 +47,36 @@ URL URL::complete_url(StringView relative_url) const return URLParser::parse(relative_url, *this); } +DeprecatedString URL::username(ApplyPercentDecoding apply_percent_decoding) const +{ + return apply_percent_decoding == ApplyPercentDecoding::Yes ? percent_decode(m_username) : m_username; +} + +DeprecatedString URL::password(ApplyPercentDecoding apply_percent_decoding) const +{ + return apply_percent_decoding == ApplyPercentDecoding::Yes ? percent_decode(m_password) : m_password; +} + +DeprecatedString URL::basename(ApplyPercentDecoding apply_percent_decoding) const +{ + if (!m_valid) + return {}; + if (m_paths.is_empty()) + return {}; + auto& last_segment = m_paths.last(); + return apply_percent_decoding == ApplyPercentDecoding::Yes ? percent_decode(last_segment) : last_segment; +} + +DeprecatedString URL::query(ApplyPercentDecoding apply_percent_decoding) const +{ + return apply_percent_decoding == ApplyPercentDecoding::Yes ? percent_decode(m_query) : m_query; +} + +DeprecatedString URL::fragment(ApplyPercentDecoding apply_percent_decoding) const +{ + return apply_percent_decoding == ApplyPercentDecoding::Yes ? percent_decode(m_fragment) : m_fragment; +} + // NOTE: This only exists for compatibility with the existing URL tests which check for both .is_null() and .is_empty(). static DeprecatedString deprecated_string_percent_encode(DeprecatedString const& input, URL::PercentEncodeSet set = URL::PercentEncodeSet::Userinfo, URL::SpaceAsPlus space_as_plus = URL::SpaceAsPlus::No) { @@ -389,15 +419,6 @@ bool URL::equals(URL const& other, ExcludeFragment exclude_fragments) const return serialize(exclude_fragments) == other.serialize(exclude_fragments); } -DeprecatedString URL::basename() const -{ - if (!m_valid) - return {}; - if (m_paths.is_empty()) - return {}; - return m_paths.last(); -} - void URL::append_percent_encoded(StringBuilder& builder, u32 code_point) { if (code_point <= 0x7f) diff --git a/AK/URL.h b/AK/URL.h index fd5b67011a..1f18fd9c04 100644 --- a/AK/URL.h +++ b/AK/URL.h @@ -53,14 +53,19 @@ public: bool is_valid() const { return m_valid; } + enum class ApplyPercentDecoding { + Yes, + No + }; DeprecatedString const& scheme() const { return m_scheme; } - DeprecatedString const& username() const { return m_username; } - DeprecatedString const& password() const { return m_password; } + DeprecatedString username(ApplyPercentDecoding = ApplyPercentDecoding::Yes) const; + DeprecatedString password(ApplyPercentDecoding = ApplyPercentDecoding::Yes) const; DeprecatedString const& host() const { return m_host; } - Vector const& paths() const { return m_paths; } - DeprecatedString const& query() const { return m_query; } - DeprecatedString const& fragment() const { return m_fragment; } + DeprecatedString basename(ApplyPercentDecoding = ApplyPercentDecoding::Yes) const; + DeprecatedString query(ApplyPercentDecoding = ApplyPercentDecoding::No) const; + DeprecatedString fragment(ApplyPercentDecoding = ApplyPercentDecoding::Yes) const; Optional port() const { return m_port; } + u16 port_or_default() const { return m_port.value_or(default_port_for_scheme(m_scheme)); } bool cannot_be_a_base_url() const { return m_cannot_be_a_base_url; } bool cannot_have_a_username_or_password_or_port() const { return m_host.is_null() || m_host.is_empty() || m_cannot_be_a_base_url || m_scheme == "file"sv; } @@ -89,7 +94,6 @@ public: } DeprecatedString path() const; - DeprecatedString basename() const; DeprecatedString serialize(ExcludeFragment = ExcludeFragment::No) const; DeprecatedString serialize_for_display() const; diff --git a/Userland/Libraries/LibWeb/URL/URL.cpp b/Userland/Libraries/LibWeb/URL/URL.cpp index 36050917c7..42d1ea372b 100644 --- a/Userland/Libraries/LibWeb/URL/URL.cpp +++ b/Userland/Libraries/LibWeb/URL/URL.cpp @@ -147,7 +147,7 @@ WebIDL::ExceptionOr URL::set_href(String const& href) m_query->m_list.clear(); // 5. Let query be this’s URL’s query. - auto& query = m_url.query(); + auto query = m_url.query(); // 6. If query is non-null, then set this’s query object’s list to the result of parsing query. if (!query.is_null()) @@ -203,7 +203,7 @@ void URL::set_username(String const& username) return; // 2. Set the username given this’s URL and the given value. - m_url.set_username(AK::URL::percent_encode(username, AK::URL::PercentEncodeSet::Userinfo)); + m_url.set_username(username.to_deprecated_string(), AK::URL::ApplyPercentEncoding::Yes); } // https://url.spec.whatwg.org/#dom-url-password @@ -223,7 +223,7 @@ void URL::set_password(String const& password) return; // 2. Set the password given this’s URL and the given value. - m_url.set_password(AK::URL::percent_encode(password, AK::URL::PercentEncodeSet::Userinfo)); + m_url.set_password(password.to_deprecated_string(), AK::URL::ApplyPercentEncoding::Yes); } // https://url.spec.whatwg.org/#dom-url-host