From 3f7b31fc78a7dd6ce82053e4fbfdfdee84445b9a Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Mon, 15 Jun 2026 12:04:58 +0200 Subject: [PATCH] LibURL: Let Host use PublicSuffixData star rule matching Ever since PublicSuffixData was created, it was using "no star rule" matching, which is what is needed for the address bar to distinguish between a domain and a search. URL::Host on the other hand requires the fallback star rule. Which rule is needed depends on the use case of the PSL. Support both use cases by a flag in PublicSuffixData. --- Libraries/LibHTTP/Cookie/Cookie.cpp | 2 +- Libraries/LibURL/Host.cpp | 80 ++++++------------------- Libraries/LibURL/PublicSuffixData.cpp | 43 ++++++++------ Libraries/LibURL/PublicSuffixData.h | 17 ++++-- Libraries/LibWebView/CookieJar.cpp | 2 +- Libraries/LibWebView/URL.cpp | 4 +- Tests/LibURL/TestPublicSuffix.cpp | 84 ++++++++++++++++----------- 7 files changed, 106 insertions(+), 126 deletions(-) diff --git a/Libraries/LibHTTP/Cookie/Cookie.cpp b/Libraries/LibHTTP/Cookie/Cookie.cpp index 1f08c27e21..b4c6a26a0e 100644 --- a/Libraries/LibHTTP/Cookie/Cookie.cpp +++ b/Libraries/LibHTTP/Cookie/Cookie.cpp @@ -162,7 +162,7 @@ bool cookie_matches_url(Cookie const& cookie, URL::URL const& url, String const& // the cookie's domain. // - The cookie's domain is not a public suffix, for user agents configured to reject "public suffixes". bool is_not_host_only_and_domain_matches = (!cookie.host_only && domain_matches(retrieval_host_canonical, cookie.domain)) - && !URL::PublicSuffixData::is_matching_public_suffix(cookie.domain); + && !URL::PublicSuffixData::is_matching_public_suffix(cookie.domain, URL::PublicSuffixData::IncludeStarRule::No); if (!is_host_only_and_has_identical_domain && !is_not_host_only_and_domain_matches) return false; diff --git a/Libraries/LibURL/Host.cpp b/Libraries/LibURL/Host.cpp index 77edb85708..ff822e759b 100644 --- a/Libraries/LibURL/Host.cpp +++ b/Libraries/LibURL/Host.cpp @@ -184,85 +184,39 @@ Optional Host::public_suffix() const { // 1. If host is not a domain, then return null. if (!is_domain()) - return OptionalNone {}; - - auto const& host_string = m_value.get(); + return {}; // 2. Let trailingDot be "." if host ends with "."; otherwise the empty string. - auto trailing_dot = host_string.ends_with('.') ? "."sv : ""sv; - // 3. Let publicSuffix be the public suffix determined by running the Public Suffix List algorithm with host as domain. [PSL] - - // NB: The PSL algorithm maintains trailing dots, so we strip it here since step 4 expects no trailing dot. - auto host_without_trailing_dot = host_string.bytes_as_string_view(); - if (!trailing_dot.is_empty()) - host_without_trailing_dot = host_without_trailing_dot.substring_view(0, host_without_trailing_dot.length() - 1); - - // FIXME: Unify this logic with registrable domain. - auto public_suffix = PublicSuffixData::find_matching_public_suffix(host_without_trailing_dot); - if (!public_suffix.has_value()) { - auto last_dot = host_without_trailing_dot.find_last('.'); - if (last_dot.has_value()) - public_suffix = MUST(String::from_utf8(host_without_trailing_dot.substring_view(last_dot.value() + 1))); - else - public_suffix = MUST(String::from_utf8(host_without_trailing_dot)); - } + auto public_suffix = PublicSuffixData::find_matching_public_suffix(*this, PublicSuffixData::IncludeStarRule::Yes); + if (!public_suffix.has_value()) + return {}; // 4. Assert: publicSuffix is an ASCII string that does not end with ".". - VERIFY(public_suffix->is_ascii()); - VERIFY(!public_suffix->ends_with('.')); - // 5. Return publicSuffix and trailingDot concatenated. - return MUST(String::formatted("{}{}", public_suffix, trailing_dot)); + // NB: PublicSuffixData preserves the host's trailing dot, if any. + VERIFY(public_suffix->is_ascii()); + return public_suffix; } // https://url.spec.whatwg.org/#host-registrable-domain Optional Host::registrable_domain() const { // 1. If host’s public suffix is null or host’s public suffix equals host, then return null. - auto public_suffix = this->public_suffix(); - if (!public_suffix.has_value() || public_suffix == m_value.get()) - return OptionalNone {}; - - // NOTE: If we got here, we know this Host is a String. - auto const& host_string = m_value.get(); + if (!is_domain()) + return {}; // 2. Let trailingDot be "." if host ends with "."; otherwise the empty string. - auto trailing_dot = host_string.ends_with('.') ? "."sv : ""sv; - // 3. Let registrableDomain be the registrable domain determined by running the Public Suffix List algorithm with host as domain. [PSL] + auto registrable_domain = PublicSuffixData::find_matching_registrable_domain(*this, PublicSuffixData::IncludeStarRule::Yes); + if (!registrable_domain.has_value()) + return {}; - // NB: The PSL algorithm maintains trailing dots, so we strip it here since step 4 expects no trailing dot. - auto without_trailing_dot = [](StringView string) { - if (string.ends_with('.')) - return string.substring_view(0, string.length() - 1); - return string; - }; - - auto host_without_trailing_dot = without_trailing_dot(host_string.bytes_as_string_view()); - auto public_suffix_without_trailing_dot = without_trailing_dot(public_suffix->bytes_as_string_view()); - - if (!host_without_trailing_dot.ends_with(public_suffix_without_trailing_dot)) - return OptionalNone {}; - - auto subhost = host_without_trailing_dot.substring_view(0, host_without_trailing_dot.length() - public_suffix_without_trailing_dot.length()); - subhost = subhost.trim("."sv, TrimMode::Right); - - if (subhost.is_empty()) - return OptionalNone {}; - - size_t start_index = 0; - if (auto index = subhost.find_last('.'); index.has_value()) - start_index = *index + 1; - - auto registrable_domain = MUST(String::from_utf8(host_without_trailing_dot.substring_view(start_index))); - - // 4. Assert: registrableDomain is an ASCII string that does not end with ".". - VERIFY(registrable_domain.is_ascii()); - VERIFY(!registrable_domain.ends_with('.')); - - // 5. Return registrableDomain and trailingDot concatenated. - return MUST(String::formatted("{}{}", registrable_domain, trailing_dot)); + // 4. Assert: publicSuffix is an ASCII string that does not end with ".". + // 5. Return publicSuffix and trailingDot concatenated. + // NB: PublicSuffixData preserves the host's trailing dot, if any. + VERIFY(registrable_domain->is_ascii()); + return registrable_domain; } } diff --git a/Libraries/LibURL/PublicSuffixData.cpp b/Libraries/LibURL/PublicSuffixData.cpp index ffff33ef05..7dd5befcc6 100644 --- a/Libraries/LibURL/PublicSuffixData.cpp +++ b/Libraries/LibURL/PublicSuffixData.cpp @@ -21,7 +21,12 @@ static psl_ctx_t const* public_suffix_context() return context; } -static constexpr auto public_suffix_match_types = PSL_TYPE_ANY | PSL_TYPE_NO_STAR_RULE; +static constexpr auto public_suffix_match_types(PublicSuffixData::IncludeStarRule include_star_rule) +{ + if (include_star_rule == PublicSuffixData::IncludeStarRule::Yes) + return PSL_TYPE_ANY; + return PSL_TYPE_ANY | PSL_TYPE_NO_STAR_RULE; +} struct NormalizedDomain { StringView host; @@ -48,13 +53,13 @@ static Optional normalized_domain_for_host(Host const& host) return NormalizedDomain { domain, trailing_dot }; } -static bool is_matching_public_suffix_impl(StringView host) +static bool is_matching_public_suffix_impl(StringView host, PublicSuffixData::IncludeStarRule include_star_rule) { ByteString lookup_host { host }; - return psl_is_public_suffix2(public_suffix_context(), lookup_host.characters(), public_suffix_match_types); + return psl_is_public_suffix2(public_suffix_context(), lookup_host.characters(), public_suffix_match_types(include_star_rule)); } -bool PublicSuffixData::is_matching_public_suffix(StringView host) +bool PublicSuffixData::is_matching_public_suffix(StringView host, IncludeStarRule include_star_rule) { if (host.is_empty()) return false; @@ -63,23 +68,23 @@ bool PublicSuffixData::is_matching_public_suffix(StringView host) if (!parsed_host.has_value()) return false; - return is_matching_public_suffix(*parsed_host); + return is_matching_public_suffix(*parsed_host, include_star_rule); } -bool PublicSuffixData::is_matching_public_suffix(Host const& host) +bool PublicSuffixData::is_matching_public_suffix(Host const& host, IncludeStarRule include_star_rule) { auto normalized_domain = normalized_domain_for_host(host); if (!normalized_domain.has_value()) return false; - return is_matching_public_suffix_impl(normalized_domain->host); + return is_matching_public_suffix_impl(normalized_domain->host, include_star_rule); } -static Optional find_matching_public_suffix_impl(StringView host) +static Optional find_matching_public_suffix_impl(StringView host, PublicSuffixData::IncludeStarRule include_star_rule) { auto remaining_host = host; while (!remaining_host.is_empty()) { - if (is_matching_public_suffix_impl(remaining_host)) + if (is_matching_public_suffix_impl(remaining_host, include_star_rule)) return MUST(String::from_utf8(remaining_host)); auto next_label_separator = remaining_host.find('.'); @@ -92,7 +97,7 @@ static Optional find_matching_public_suffix_impl(StringView host) return OptionalNone {}; } -Optional PublicSuffixData::find_matching_public_suffix(StringView string) +Optional PublicSuffixData::find_matching_public_suffix(StringView string, IncludeStarRule include_star_rule) { if (string.is_empty()) return {}; @@ -101,26 +106,26 @@ Optional PublicSuffixData::find_matching_public_suffix(StringView string if (!parsed_host.has_value()) return {}; - return find_matching_public_suffix(*parsed_host); + return find_matching_public_suffix(*parsed_host, include_star_rule); } -Optional PublicSuffixData::find_matching_public_suffix(Host const& host) +Optional PublicSuffixData::find_matching_public_suffix(Host const& host, IncludeStarRule include_star_rule) { auto normalized_domain = normalized_domain_for_host(host); if (!normalized_domain.has_value()) return {}; - auto public_suffix = find_matching_public_suffix_impl(normalized_domain->host); + auto public_suffix = find_matching_public_suffix_impl(normalized_domain->host, include_star_rule); if (!public_suffix.has_value()) return {}; return MUST(String::formatted("{}{}", public_suffix.value(), normalized_domain->trailing_dot)); } -static Optional find_matching_registrable_domain_impl(StringView host) +static Optional find_matching_registrable_domain_impl(StringView host, PublicSuffixData::IncludeStarRule include_star_rule) { // find_matching_public_suffix_impl() always returns a tail of host, so it is by construction a suffix of it. - auto public_suffix = find_matching_public_suffix_impl(host); + auto public_suffix = find_matching_public_suffix_impl(host, include_star_rule); if (!public_suffix.has_value() || host == *public_suffix) return {}; @@ -137,7 +142,7 @@ static Optional find_matching_registrable_domain_impl(StringView host) return MUST(String::from_utf8(host.substring_view(start_index))); } -Optional PublicSuffixData::find_matching_registrable_domain(StringView string) +Optional PublicSuffixData::find_matching_registrable_domain(StringView string, IncludeStarRule include_star_rule) { if (string.is_empty()) return {}; @@ -146,16 +151,16 @@ Optional PublicSuffixData::find_matching_registrable_domain(StringView s if (!parsed_host.has_value()) return {}; - return find_matching_registrable_domain(*parsed_host); + return find_matching_registrable_domain(*parsed_host, include_star_rule); } -Optional PublicSuffixData::find_matching_registrable_domain(Host const& host) +Optional PublicSuffixData::find_matching_registrable_domain(Host const& host, IncludeStarRule include_star_rule) { auto normalized_domain = normalized_domain_for_host(host); if (!normalized_domain.has_value()) return {}; - auto registrable_domain = find_matching_registrable_domain_impl(normalized_domain->host); + auto registrable_domain = find_matching_registrable_domain_impl(normalized_domain->host, include_star_rule); if (!registrable_domain.has_value()) return {}; diff --git a/Libraries/LibURL/PublicSuffixData.h b/Libraries/LibURL/PublicSuffixData.h index 882f844e73..b18e199044 100644 --- a/Libraries/LibURL/PublicSuffixData.h +++ b/Libraries/LibURL/PublicSuffixData.h @@ -14,12 +14,17 @@ namespace URL { class PublicSuffixData { public: - static bool is_matching_public_suffix(StringView host); - static bool is_matching_public_suffix(Host const& host); - static Optional find_matching_public_suffix(StringView string); - static Optional find_matching_public_suffix(Host const& host); - static Optional find_matching_registrable_domain(StringView string); - static Optional find_matching_registrable_domain(Host const& host); + enum class IncludeStarRule { + No, + Yes, + }; + + static bool is_matching_public_suffix(StringView host, IncludeStarRule); + static bool is_matching_public_suffix(Host const& host, IncludeStarRule); + static Optional find_matching_public_suffix(StringView string, IncludeStarRule); + static Optional find_matching_public_suffix(Host const& host, IncludeStarRule); + static Optional find_matching_registrable_domain(StringView string, IncludeStarRule); + static Optional find_matching_registrable_domain(Host const& host, IncludeStarRule); }; } diff --git a/Libraries/LibWebView/CookieJar.cpp b/Libraries/LibWebView/CookieJar.cpp index 3963bfec65..854db1a623 100644 --- a/Libraries/LibWebView/CookieJar.cpp +++ b/Libraries/LibWebView/CookieJar.cpp @@ -228,7 +228,7 @@ ErrorOr CookieJar::set_cookie(URL::URL const& url, HTTP::Cookie::ParsedCoo return Error::from_string_literal("Cookie URL host cannot be canonicalized"); // 9. If the user agent is configured to reject "public suffixes" and the domain-attribute is a public suffix: - if (URL::PublicSuffixData::is_matching_public_suffix(domain_attribute)) { + if (URL::PublicSuffixData::is_matching_public_suffix(domain_attribute, URL::PublicSuffixData::IncludeStarRule::No)) { // 1. Let request-host-canonical be the canonicalized request-host. // 2. If request-host fails to be canonicalized then abort this algorithm and ignore the cookie entirely. diff --git a/Libraries/LibWebView/URL.cpp b/Libraries/LibWebView/URL.cpp index 540360511c..1ce176b3a7 100644 --- a/Libraries/LibWebView/URL.cpp +++ b/Libraries/LibWebView/URL.cpp @@ -63,7 +63,7 @@ Optional sanitize_url(StringView location, Optional cons if (any_of(RESERVED_TLDS, [&](StringView const& tld) { return domain.byte_count() > tld.length() && domain.ends_with_bytes(tld); })) return url; - auto public_suffix = URL::PublicSuffixData::find_matching_public_suffix(domain); + auto public_suffix = URL::PublicSuffixData::find_matching_public_suffix(domain, URL::PublicSuffixData::IncludeStarRule::No); if (!public_suffix.has_value() || *public_suffix == domain) { if (append_tld == AppendTLD::Yes) url->set_host(MUST(String::formatted("{}.com", domain))); @@ -248,7 +248,7 @@ static URLParts break_web_url_into_parts(URL::URL const& url, StringView url_str domain = url_without_scheme; } - auto public_suffix = URL::PublicSuffixData::find_matching_public_suffix(domain); + auto public_suffix = URL::PublicSuffixData::find_matching_public_suffix(domain, URL::PublicSuffixData::IncludeStarRule::No); if (!public_suffix.has_value() || !domain.ends_with(*public_suffix)) return { scheme, domain, remainder }; diff --git a/Tests/LibURL/TestPublicSuffix.cpp b/Tests/LibURL/TestPublicSuffix.cpp index 591b0fab45..aecb216441 100644 --- a/Tests/LibURL/TestPublicSuffix.cpp +++ b/Tests/LibURL/TestPublicSuffix.cpp @@ -50,15 +50,17 @@ TEST_CASE(public_suffix_matching_for_psl_rules) }; for (auto const& test_case : test_cases) { - EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(test_case.input), test_case.is_public_suffix); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(test_case.input), test_case.public_suffix); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(test_case.input), test_case.registrable_domain); + auto exclude_star_rule = URL::PublicSuffixData::IncludeStarRule::No; + + EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(test_case.input, exclude_star_rule), test_case.is_public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(test_case.input, exclude_star_rule), test_case.public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(test_case.input, exclude_star_rule), test_case.registrable_domain); auto host = URL::Parser::parse_host(test_case.input); VERIFY(host.has_value()); - EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(*host), test_case.is_public_suffix); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host), test_case.public_suffix); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host), test_case.registrable_domain); + EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(*host, exclude_star_rule), test_case.is_public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host, exclude_star_rule), test_case.public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host, exclude_star_rule), test_case.registrable_domain); EXPECT_EQ(host->public_suffix(), test_case.public_suffix); EXPECT_EQ(host->registrable_domain(), test_case.registrable_domain); } @@ -68,36 +70,46 @@ TEST_CASE(public_suffix_matching_without_psl_rule) { struct TestCase { StringView input; + bool is_public_suffix_with_star_rule; Optional host_public_suffix; Optional host_registrable_domain; }; TestCase test_cases[] { - { "foobar"sv, "foobar"sv, OptionalNone {} }, - { "foobar."sv, "foobar."sv, OptionalNone {} }, - { "not-a-public-suffix"sv, "not-a-public-suffix"sv, OptionalNone {} }, - { "a.example"sv, "example"sv, "a.example"sv }, - { "a.example."sv, "example."sv, "a.example."sv }, - { "b.b.example"sv, "example"sv, "b.example"sv }, - { "b.b.example."sv, "example."sv, "b.example."sv }, - { "foo.not-a-public-suffix"sv, "not-a-public-suffix"sv, "foo.not-a-public-suffix"sv }, - { "sub.foo.not-a-public-suffix"sv, "not-a-public-suffix"sv, "foo.not-a-public-suffix"sv }, - { "إختبار"sv, "xn--kgbechtv"sv, OptionalNone {} }, - { "example.إختبار"sv, "xn--kgbechtv"sv, "example.xn--kgbechtv"sv }, - { "example.إختبار."sv, "xn--kgbechtv."sv, "example.xn--kgbechtv."sv }, - { "sub.example.إختبار"sv, "xn--kgbechtv"sv, "example.xn--kgbechtv"sv }, + { "foobar"sv, true, "foobar"sv, OptionalNone {} }, + { "foobar."sv, true, "foobar."sv, OptionalNone {} }, + { "not-a-public-suffix"sv, true, "not-a-public-suffix"sv, OptionalNone {} }, + { "a.example"sv, false, "example"sv, "a.example"sv }, + { "a.example."sv, false, "example."sv, "a.example."sv }, + { "b.b.example"sv, false, "example"sv, "b.example"sv }, + { "b.b.example."sv, false, "example."sv, "b.example."sv }, + { "foo.not-a-public-suffix"sv, false, "not-a-public-suffix"sv, "foo.not-a-public-suffix"sv }, + { "sub.foo.not-a-public-suffix"sv, false, "not-a-public-suffix"sv, "foo.not-a-public-suffix"sv }, + { "إختبار"sv, true, "xn--kgbechtv"sv, OptionalNone {} }, + { "example.إختبار"sv, false, "xn--kgbechtv"sv, "example.xn--kgbechtv"sv }, + { "example.إختبار."sv, false, "xn--kgbechtv."sv, "example.xn--kgbechtv."sv }, + { "sub.example.إختبار"sv, false, "xn--kgbechtv"sv, "example.xn--kgbechtv"sv }, }; for (auto const& test_case : test_cases) { - EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(test_case.input)); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(test_case.input), OptionalNone {}); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(test_case.input), OptionalNone {}); + auto exclude_star_rule = URL::PublicSuffixData::IncludeStarRule::No; + auto include_star_rule = URL::PublicSuffixData::IncludeStarRule::Yes; + + EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(test_case.input, exclude_star_rule)); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(test_case.input, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(test_case.input, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(test_case.input, include_star_rule), test_case.is_public_suffix_with_star_rule); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(test_case.input, include_star_rule), test_case.host_public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(test_case.input, include_star_rule), test_case.host_registrable_domain); auto host = URL::Parser::parse_host(test_case.input); VERIFY(host.has_value()); - EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(*host)); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host), OptionalNone {}); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host), OptionalNone {}); + EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(*host, exclude_star_rule)); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::is_matching_public_suffix(*host, include_star_rule), test_case.is_public_suffix_with_star_rule); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host, include_star_rule), test_case.host_public_suffix); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host, include_star_rule), test_case.host_registrable_domain); EXPECT_EQ(host->public_suffix(), test_case.host_public_suffix); EXPECT_EQ(host->registrable_domain(), test_case.host_registrable_domain); } @@ -116,11 +128,13 @@ TEST_CASE(invalid_hosts) // Above inputs are not valid hosts, so should not be able to be parsed or matched in the PSL. for (auto const& input : raw_invalid_inputs) { + auto exclude_star_rule = URL::PublicSuffixData::IncludeStarRule::No; + auto host = URL::Parser::parse_host(input); EXPECT(!host.has_value()); - EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(input)); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(input), OptionalNone {}); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(input), OptionalNone {}); + EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(input, exclude_star_rule)); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(input, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(input, exclude_star_rule), OptionalNone {}); } } @@ -132,15 +146,17 @@ TEST_CASE(public_suffix_matching_for_ip_addresses) }; for (auto const& input : test_cases) { - EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(input)); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(input), OptionalNone {}); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(input), OptionalNone {}); + auto exclude_star_rule = URL::PublicSuffixData::IncludeStarRule::No; + + EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(input, exclude_star_rule)); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(input, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(input, exclude_star_rule), OptionalNone {}); auto host = URL::Parser::parse_host(input); VERIFY(host.has_value()); - EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(*host)); - EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host), OptionalNone {}); - EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host), OptionalNone {}); + EXPECT(!URL::PublicSuffixData::is_matching_public_suffix(*host, exclude_star_rule)); + EXPECT_EQ(URL::PublicSuffixData::find_matching_public_suffix(*host, exclude_star_rule), OptionalNone {}); + EXPECT_EQ(URL::PublicSuffixData::find_matching_registrable_domain(*host, exclude_star_rule), OptionalNone {}); EXPECT_EQ(host->public_suffix(), OptionalNone {}); EXPECT_EQ(host->registrable_domain(), OptionalNone {}); }