Chrome · API
CVE-2026-106422
Authorization Error in API
Overview
Low
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifcomponents/content_settings/core/common/content_settings_pattern.cc |
modified | |
whilecomponents/content_settings/core/common/content_settings_pattern.cc |
modified | |
forcomponents/url_pattern_index/url_pattern_index.cc |
modified | |
TESTcomponents/content_settings/core/common/content_settings_pattern_unittest.cc |
modified |
Files Changed
components/url_pattern_index/url_pattern_index.cccomponents/content_settings/core/common/content_settings_pattern_unittest.cccomponents/content_settings/core/common/content_settings_pattern.cccomponents/url_pattern_index/url_pattern_index_unittest.cc
Patch
From ea54f4b92b8701fe399346b02d6a6c3388baad1b Mon Sep 17 00:00:00 2001
From: Dominic Battre <battre@chromium.org>
Date: Wed, 16 Sep 2026 02:12:47 -0700
Subject: [PATCH] Reland "Reland "Fix trailing dot normalization bypasses.""
This reverts commit c71bfcc01a4cbb1c2765fb56a5415e0f014a1c2a.
Reason for revert: Fixes to logic that broke the fuzz tests.
Original change's description:
> Revert "Reland "Fix trailing dot normalization bypasses.""
>
> This reverts commit bd5707e4b57c6edb080dc4718b6e51497a718403.
>
> Reason for revert: more problems with fuzzer
>
> Failure Link: https://issues.chromium.org/issues/560465534, https://issues.chromium.org/issues/560246192
>
>
>
> Original change's description:
> > Reland "Fix trailing dot normalization bypasses."
> >
> > This reverts commit 1a015be3b28655f2c61d4a4be1f229f3dafe6419.
> >
> > Reason for revert: This CL fixes idempotency for content settings.
> >
> > Original change's description:
> > > Revert "Fix trailing dot normalization bypasses."
> > >
> > > This reverts commit 5ee694c112b1dd9d04b441f5b0e27eb10bbbb759.
> > >
> > > Reason for revert: This broke the fuzzing tests because it broke idempotency. Want to reland a version that contains https://chromium-review.git.corp.google.com/c/chromium/src/+/8382808/1
> > >
> > > Failure Link: b:559255785
> > >
> > > Original change's description:
> > > > Fix trailing dot normalization bypasses.
> > > >
> > > > This CL fixes issues where hostnames with multiple trailing dots could
> > > > bypass domain-based filters in Declarative Net Request (DNR) and
> > > > subresource_filter.
> > > >
> > > > After this CL we should review all call sites of IsDomain to decide
> > > > whether they should be changed to DomainIsIgnoringTrailingDots.
> > > >
> > > > TAG=agy
> > > > CONV=ebcc4572-5439-4145-af7c-6acdf5c1da58
> > > >
> > > > Bug: 519458746
> > > > Change-Id: Ic1f03aaa857ffc52d57254fe744842a4c24e69c2
> > > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8074441
> > > > Commit-Queue: Dominic Battré <battre@chromium.org>
> > > > Reviewed-by: Balazs Engedy <engedy@chromium.org>
> > > > Cr-Commit-Position: refs/heads/main@{#1694536}
> > >
> > > Bug: 519458746, 559255785
> > > No-Presubmit: true
> > > No-Tree-Checks: true
> > > No-Try: true
> > > Bug: 519458746
> > > Change-Id: Ie56e3e8988d1a9f8f75676176c502e45620c1ae8
> > > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8379446
> > > Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> > > Reviewed-by: Balazs Engedy <engedy@chromium.org>
> > > Commit-Queue: Dominic Battré <battre@chromium.org>
> > > Cr-Commit-Position: refs/heads/main@{#1695332}
> >
> > Bug: 519458746, 559255785
> > Bug: 519458746
> > Change-Id: Ie6454d2372b06b449ed93739e1b5ec5f067ab3dd
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8380659
> > Reviewed-by: Balazs Engedy <engedy@chromium.org>
> > Auto-Submit: Dominic Battré <battre@chromium.org>
> > Commit-Queue: Balazs Engedy <engedy@chromium.org>
> > Cr-Commit-Position: refs/heads/main@{#1696115}
>
> Bug: 519458746, 559255785
> Bug: 519458746
> Change-Id: I749c23d92a54067b8b2cdb41db87e0826775d01d
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8406065
> Reviewed-by: Balazs Engedy <engedy@chromium.org>
> Commit-Queue: Dominic Battré <battre@chromium.org>
> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
> Cr-Commit-Position: refs/heads/main@{#1697245}
Bug: 519458746, 559255785
Bug: 519458746
Change-Id: I86484354de41a3cf3881181217e9b7514e8d5d80
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8409409
Reviewed-by: Balazs Engedy <engedy@chromium.org>
Commit-Queue: Dominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1698769}
---
diff --git a/components/content_settings/core/common/content_settings_pattern.cc b/components/content_settings/core/common/content_settings_pattern.cc
index 8ddebace..8a88770e 100644
--- a/components/content_settings/core/common/content_settings_pattern.cc
+++ b/components/content_settings/core/common/content_settings_pattern.cc
@@ -168,6 +168,12 @@
// the canonicalization was successful.
static bool Canonicalize(PatternParts* parts);
+ // Canonicalizes the host part. Repeating the process ensures that hosts with
+ // trailing dots that were not visible before canonicalization (e.g. because
+ // UTS#46 / IDNA stripped ignorable characters after trailing dots, or mapped
+ // Unicode fullwidth dots) are trimmed and re-canonicalized consistently.
+ static bool CanonicalizeHost(PatternParts* parts);
+
// Returns true when the pattern |parts| represent a valid pattern.
static bool Validate(const PatternParts& parts);
@@ -280,44 +286,59 @@
}
}
- // Canonicalize the host part.
- url::CanonHostInfo host_info;
- std::string canonicalized_host;
- if (parts->scheme == url::kFileScheme) {
- canonicalized_host = net::CanonicalizeFileHost(parts->host, &host_info);
- } else {
- canonicalized_host = net::CanonicalizeHost(parts->host, &host_info);
- }
+ return CanonicalizeHost(parts);
+}
- if (host_info.IsIPAddress() && parts->has_domain_wildcard) {
- return false;
- }
+// static
+bool ContentSettingsPattern::Builder::CanonicalizeHost(PatternParts* parts) {
+ // Canonicalize the host part. Repeating the process ensures that hosts with
+ // trailing dots that were not visible before canonicalization (e.g. because
+ // UTS#46 / IDNA stripped ignorable characters after trailing dots, or mapped
+ // Unicode fullwidth dots) are trimmed and re-canonicalized consistently.
+ while (true) {
+ while (parts->host.length() > 1 && parts->host.ends_with(".")) {
+ parts->host.pop_back();
+ }
- // A domain wildcard pattern involves exactly one separating dot, inside the
- // square brackets. This is a common misunderstanding of that pattern that we
- // want to check for. See: https://crbug.com/823706.
- if (parts->has_domain_wildcard && base::StartsWith(canonicalized_host, ".")) {
- return false;
- }
+ url::CanonHostInfo host_info;
+ std::string canonicalized_host;
+ if (parts->scheme == url::kFileScheme) {
+ canonicalized_host = net::CanonicalizeFileHost(parts->host, &host_info);
+ } else {
+ canonicalized_host = net::CanonicalizeHost(parts->host, &host_info);
+ }
- // Omit a single ending dot as long as there is at least one non-dot character
- // before it, which is in line with the behavior of net::TrimEndingDot; but
- // consider two ending dots an invalid pattern, otherwise canonicalization of
- // a canonical pattern would not be idempotent.
- if (base::EndsWith(canonicalized_host, "..", base::CompareCase::SENSITIVE)) {
- return false;
- } else if (canonicalized_host.size() >= 2u &&
- base::EndsWith(canonicalized_host, ".",
- base::CompareCase::SENSITIVE)) {
- canonicalized_host.pop_back();
- }
+ if (host_info.family == url::CanonHostInfo::BROKEN) {
+ return false;
+ }
- if ((parts->host.find('*') == std::string::npos) &&
- !canonicalized_host.empty()) {
- // Valid host.
+ if (host_info.IsIPAddress() && parts->has_domain_wildcard) {
+ return false;
+ }
+
+ // A domain wildcard pattern involves exactly one separating dot, inside the
+ // square brackets. This is a common misunderstanding of that pattern that
+ // we want to check for. See: https://crbug.com/823706.
+ if (parts->has_domain_wildcard &&
+ base::StartsWith(canonicalized_host, ".")) {
+ return false;
+ }
+
+ while (canonicalized_host.length() > 1 &&
+ canonicalized_host.ends_with(".")) {
+ canonicalized_host.pop_back();
+ }
+
+ if (parts->host.find('*') != std::string::npos ||
+ canonicalized_host.empty()) {
+ parts->host.clear();
+ break;
+ }
+
+ if (parts->host == canonicalized_host) {
+ break;
+ }
parts->host = std::move(canonicalized_host);
- } else {
- parts->host.clear();
}
return true;
@@ -633,11 +654,9 @@
return parts_.is_path_wildcard || parts_.path == local_url->path();
}
- // Match the host part. Code is the same as url::TrimEndingDot but that method
- // unnecessarily creates a new std::string.
+ // Match the host part, removing all trailing dots.
std::string_view trimmed_host = local_url->host();
- size_t len = trimmed_host.length();
- if (len > 1 && trimmed_host[len - 1] == '.') {
+ while (trimmed_host.length() > 1 && trimmed_host.back() == '.') {
trimmed_host.remove_suffix(1);
}
diff --git a/components/url_pattern_index/url_pattern_index.cc b/components/url_pattern_index/url_pattern_index.cc
index b46c0b9..ccb2c25bf 100644
--- a/components/url_pattern_index/url_pattern_index.cc
+++ b/components/url_pattern_index/url_pattern_index.cc
@@ -235,17 +235,24 @@
domains_included.reserve(domains_size);
for (const auto& domain_list_item : domain_list_items) {
- const std::string& domain = domain_list_item.domain();
+ std::string_view domain = domain_list_item.domain();
// Non-ascii characters in domains are unsupported.
if (!base::IsStringASCII(domain))
return false;
+ // Trimming trailing dots from the domain.
+ while (domain.length() > 1 && domain.back() == '.') {
+ domain.remove_suffix(1);
+ }
+
// Note: This is not always correct. Chrome's URL parser uses upper-case
// for percent encoded hosts. E.g. https://,.com is encoded as
// https://%2C.com.
- auto offset = builder->CreateSharedString(
- HasNoUpperAscii(domain) ? domain : base::ToLowerASCII(domain));
+ std::string domain_lower = HasNoUpperAscii(domain)
+ ? std::string(domain)
+ : base::ToLowerASCII(domain);
+ auto offset = builder->CreateSharedString(domain_lower);
if (domain_list_item.exclude())
domains_excluded.push_back(offset);
@@ -584,22 +591,24 @@
if (host.empty())
return 0;
+ // If the host name ends with dots, then ignore them.
+ while (host.length() > 1 && host.back() == '.') {
+ host.remove_suffix(1);
+ }
+
// If the |domains| list is short, then the simple strategy is usually faster.
if (domains.size() <= 5) {
for (auto* domain : domains) {
const std::string_view domain_piece = ToStringView(domain);
- if (url::DomainIs(host, domain_piece))
+ if (url::DomainIs(host, domain_piece)) {
return domain_piece.size();
+ }
}
return 0;
}
// Otherwise look for each subdomain of the `host` using binary search.
- // If the host name ends with a dot, then ignore it.
- if (host.back() == '.')
- host.remove_suffix(1);
-
// The |left| bound of the search is shared between iterations, because
// subdomains are considered in decreasing order of their lengths, therefore
// each consecutive lower_bound will be at least as far as the previous.
diff --git a/components/content_settings/core/common/content_settings_pattern_unittest.cc b/components/content_settings/core/common/content_settings_pattern_unittest.cc
index df92c3a2..8d7d9e5 100644
--- a/components/content_settings/core/common/content_settings_pattern_unittest.cc
+++ b/components/content_settings/core/common/content_settings_pattern_unittest.cc
@@ -344,12 +344,19 @@
ContentSettingsPattern::Wildcard()));
}
-TEST(ContentSettingsPatternTest, TrimEndingDotFromHost) {
+TEST(ContentSettingsPatternTest, TrimTrailingDotsFromHost) {
EXPECT_TRUE(Pattern("www.example.com").IsValid());
EXPECT_TRUE(
Pattern("www.example.com").Matches(GURL("http://www.example.com")));
EXPECT_TRUE(
Pattern("www.example.com").Matches(GURL("http://www.example.com.")));
+ EXPECT_TRUE(
+ Pattern("www.example.com").Matches(GURL("http://www.example.com..")));
+
+ EXPECT_TRUE(
+ Pattern("https://example.com..").Matches(GURL("https://example.com")));
+ EXPECT_TRUE(
+ Pattern("https://example.com").Matches(GURL("https://example.com..")));
EXPECT_TRUE(Pattern("www.example.com.").IsValid());
EXPECT_STREQ("www.example.com",
@@ -357,6 +364,9 @@
EXPECT_TRUE(Pattern("www.example.com.") == Pattern("www.example.com"));
EXPECT_TRUE(Pattern("www.example.com.") == Pattern("www.example.com."));
+ EXPECT_TRUE(Pattern("www.example.com..") == Pattern("www.example.com"));
+ EXPECT_TRUE(Pattern("http://www.example.com..") ==
+ Pattern("http://www.example.com"));
EXPECT_TRUE(Pattern(".").IsValid());
EXPECT_STREQ(".", Pattern(".").ToString().c_str());
@@ -370,8 +380,41 @@
EXPECT_STREQ("a..b", Pattern("a..b.").ToString().c_str());
EXPECT_TRUE(Pattern("a..b.").Matches(GURL("http://a..b.")));
- EXPECT_FALSE(Pattern("..").IsValid());
- EXPECT_FALSE(Pattern("a..").IsValid());
+ EXPECT_TRUE(Pattern("..").IsValid()); // Equivalent to Pattern(".").
+ EXPECT_TRUE(Pattern("a..").IsValid()); // Equivalent to Pattern("a").
+
+ // Hosts that end in a numeric label (or punycode resulting in one) are
+ // treated as IPv4 addresses per WHATWG URL spec. When preceding labels are
+ // non-numeric, they are broken IPv4 addresses and must be rejected even when
+ // multiple trailing dots are present.
+ EXPECT_FALSE(Pattern("example.2").IsValid());
+ EXPECT_FALSE(Pattern("example.2.").IsValid());
+ EXPECT_FALSE(Pattern("example.2..").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2.").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2..").IsValid());
+
+ // Trailing dots disguised by ignorable characters (like soft hyphen U+00AD)
+ // or fullwidth/ideographic dots must be handled consistently and rejected if
+ // broken.
+ EXPECT_FALSE(Pattern("example.2.\xc2\xad").IsValid());
+ EXPECT_FALSE(Pattern("example.2\xe3\x80\x82").IsValid());
+ EXPECT_FALSE(Pattern("example.2\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_FALSE(
+ Pattern("...........\xc2\xad....1....\xc2\xad..........\xc2\xad....")
+ .IsValid());
+
+ // Valid patterns with trailing dots or non-ASCII dots that resolve to IPv4.
+ EXPECT_TRUE(Pattern("1..").IsValid());
+ EXPECT_STREQ("0.0.0.1", Pattern("1..").ToString().c_str());
+ EXPECT_TRUE(Pattern("1..") == Pattern("0.0.0.1"));
+ EXPECT_TRUE(Pattern("1\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_STREQ("0.0.0.1",
+ Pattern("1\xe3\x80\x82\xe3\x80\x82").ToString().c_str());
+ EXPECT_TRUE(Pattern("example.com\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_STREQ(
+ "example.com",
+ Pattern("example.com\xe3\x80\x82\xe3\x80\x82").ToString().c_str());
}
TEST(ContentSettingsPatternTest, FromString_WithNoWildcards) {
@@ -743,10 +786,6 @@
// Invalid file pattern strings.
EXPECT_FALSE(Pattern("file://").IsValid());
EXPECT_STREQ("", Pattern("file://").ToString().c_str());
-
- // Host having multiple ending dots.
- EXPECT_FALSE(Pattern("www.example.com..").IsValid());
- EXPECT_STREQ("", Pattern("www.example.com..").ToString().c_str());
}
TEST(ContentSettingsPatternTest, UnequalOperator) {
diff --git a/components/url_pattern_index/url_pattern_index_unittest.cc b/components/url_pattern_index/url_pattern_index_unittest.cc
index e8cdcf86..806a86fe 100644
--- a/components/url_pattern_index/url_pattern_index_unittest.cc
+++ b/components/url_pattern_index/url_pattern_index_unittest.cc
@@ -447,13 +447,72 @@
{{"domain.com"}, "http://.domain.com", true},
{{"domain.com"}, "http://.domain.com.", true},
{{".domain.com"}, "http://.domain.com", true},
- {{"domain.com."}, "http://domain.com", false},
+ {{"domain.com."}, "http://domain.com", true},
{{"domain.com."}, "http://domain.com.", true},
+ {{"domain.com.."}, "http://domain.com", true},
+ {{"domain.com.."}, "http://domain.com.", true},
+ {{"domain.com.."}, "http://domain.com..", true},
+ {{"domain.com..."}, "http://domain.com", true},
+ {{"domain.com..."}, "http://domain.com..", true},
{{"domain..com"}, "http://domain.com", false},
{{"domain.com"}, "http://domain..com", false},
{{"domain..com"}, "http://domain..com", true},
+ // Multiple trailing dots.
+ {{"domain.com"}, "http://domain.com..", true},
+ {{"domain.com"}, "http://domain.com...", true},
+ {{"domain.com"}, "http://sub.domain.com..", true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com"},
+ "http://domain.com..",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com"},
+ "http://domain.com...",
... (file diff truncated)
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/components/content_settings/core/common/content_settings_pattern_unittest.cc b/components/content_settings/core/common/content_settings_pattern_unittest.cc
index df92c3a2..8d7d9e5 100644
--- a/components/content_settings/core/common/content_settings_pattern_unittest.cc
+++ b/components/content_settings/core/common/content_settings_pattern_unittest.cc
@@ -344,12 +344,19 @@
ContentSettingsPattern::Wildcard()));
}
-TEST(ContentSettingsPatternTest, TrimEndingDotFromHost) {
+TEST(ContentSettingsPatternTest, TrimTrailingDotsFromHost) {
EXPECT_TRUE(Pattern("www.example.com").IsValid());
EXPECT_TRUE(
Pattern("www.example.com").Matches(GURL("http://www.example.com")));
EXPECT_TRUE(
Pattern("www.example.com").Matches(GURL("http://www.example.com.")));
+ EXPECT_TRUE(
+ Pattern("www.example.com").Matches(GURL("http://www.example.com..")));
+
+ EXPECT_TRUE(
+ Pattern("https://example.com..").Matches(GURL("https://example.com")));
+ EXPECT_TRUE(
+ Pattern("https://example.com").Matches(GURL("https://example.com..")));
EXPECT_TRUE(Pattern("www.example.com.").IsValid());
EXPECT_STREQ("www.example.com",
@@ -357,6 +364,9 @@
EXPECT_TRUE(Pattern("www.example.com.") == Pattern("www.example.com"));
EXPECT_TRUE(Pattern("www.example.com.") == Pattern("www.example.com."));
+ EXPECT_TRUE(Pattern("www.example.com..") == Pattern("www.example.com"));
+ EXPECT_TRUE(Pattern("http://www.example.com..") ==
+ Pattern("http://www.example.com"));
EXPECT_TRUE(Pattern(".").IsValid());
EXPECT_STREQ(".", Pattern(".").ToString().c_str());
@@ -370,8 +380,41 @@
EXPECT_STREQ("a..b", Pattern("a..b.").ToString().c_str());
EXPECT_TRUE(Pattern("a..b.").Matches(GURL("http://a..b.")));
- EXPECT_FALSE(Pattern("..").IsValid());
- EXPECT_FALSE(Pattern("a..").IsValid());
+ EXPECT_TRUE(Pattern("..").IsValid()); // Equivalent to Pattern(".").
+ EXPECT_TRUE(Pattern("a..").IsValid()); // Equivalent to Pattern("a").
+
+ // Hosts that end in a numeric label (or punycode resulting in one) are
+ // treated as IPv4 addresses per WHATWG URL spec. When preceding labels are
+ // non-numeric, they are broken IPv4 addresses and must be rejected even when
+ // multiple trailing dots are present.
+ EXPECT_FALSE(Pattern("example.2").IsValid());
+ EXPECT_FALSE(Pattern("example.2.").IsValid());
+ EXPECT_FALSE(Pattern("example.2..").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2.").IsValid());
+ EXPECT_FALSE(Pattern("9127.xn-91ԵxhԸ.0chr-Ὲ.2..").IsValid());
+
+ // Trailing dots disguised by ignorable characters (like soft hyphen U+00AD)
+ // or fullwidth/ideographic dots must be handled consistently and rejected if
+ // broken.
+ EXPECT_FALSE(Pattern("example.2.\xc2\xad").IsValid());
+ EXPECT_FALSE(Pattern("example.2\xe3\x80\x82").IsValid());
+ EXPECT_FALSE(Pattern("example.2\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_FALSE(
+ Pattern("...........\xc2\xad....1....\xc2\xad..........\xc2\xad....")
+ .IsValid());
+
+ // Valid patterns with trailing dots or non-ASCII dots that resolve to IPv4.
+ EXPECT_TRUE(Pattern("1..").IsValid());
+ EXPECT_STREQ("0.0.0.1", Pattern("1..").ToString().c_str());
+ EXPECT_TRUE(Pattern("1..") == Pattern("0.0.0.1"));
+ EXPECT_TRUE(Pattern("1\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_STREQ("0.0.0.1",
+ Pattern("1\xe3\x80\x82\xe3\x80\x82").ToString().c_str());
+ EXPECT_TRUE(Pattern("example.com\xe3\x80\x82\xe3\x80\x82").IsValid());
+ EXPECT_STREQ(
+ "example.com",
+ Pattern("example.com\xe3\x80\x82\xe3\x80\x82").ToString().c_str());
}
TEST(ContentSettingsPatternTest, FromString_WithNoWildcards) {
@@ -743,10 +786,6 @@
// Invalid file pattern strings.
EXPECT_FALSE(Pattern("file://").IsValid());
EXPECT_STREQ("", Pattern("file://").ToString().c_str());
-
- // Host having multiple ending dots.
- EXPECT_FALSE(Pattern("www.example.com..").IsValid());
- EXPECT_STREQ("", Pattern("www.example.com..").ToString().c_str());
}
TEST(ContentSettingsPatternTest, UnequalOperator) {
diff --git a/components/url_pattern_index/url_pattern_index_unittest.cc b/components/url_pattern_index/url_pattern_index_unittest.cc
index e8cdcf86..806a86fe 100644
--- a/components/url_pattern_index/url_pattern_index_unittest.cc
+++ b/components/url_pattern_index/url_pattern_index_unittest.cc
@@ -447,13 +447,72 @@
{{"domain.com"}, "http://.domain.com", true},
{{"domain.com"}, "http://.domain.com.", true},
{{".domain.com"}, "http://.domain.com", true},
- {{"domain.com."}, "http://domain.com", false},
+ {{"domain.com."}, "http://domain.com", true},
{{"domain.com."}, "http://domain.com.", true},
+ {{"domain.com.."}, "http://domain.com", true},
+ {{"domain.com.."}, "http://domain.com.", true},
+ {{"domain.com.."}, "http://domain.com..", true},
+ {{"domain.com..."}, "http://domain.com", true},
+ {{"domain.com..."}, "http://domain.com..", true},
{{"domain..com"}, "http://domain.com", false},
{{"domain.com"}, "http://domain..com", false},
{{"domain..com"}, "http://domain..com", true},
+ // Multiple trailing dots.
+ {{"domain.com"}, "http://domain.com..", true},
+ {{"domain.com"}, "http://domain.com...", true},
+ {{"domain.com"}, "http://sub.domain.com..", true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com"},
+ "http://domain.com..",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com"},
+ "http://domain.com...",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com"},
+ "http://sub.domain.com..",
+ true},
+ {{"~domain.com"}, "http://domain.com..", false},
+ {{"~domain.com"}, "http://sub.domain.com..", false},
+ {{"~d1.com", "~d2.com", "~d3.com", "~d4.com", "~d5.com", "~domain.com"},
+ "http://domain.com..",
+ false},
+ {{"~d1.com", "~d2.com", "~d3.com", "~d4.com", "~d5.com", "~domain.com"},
+ "http://sub.domain.com..",
+ false},
+
+ // Trailing dots on rules in long domain lists (> 5 domains, binary
+ // search path).
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com."},
+ "http://domain.com",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com."},
+ "http://domain.com.",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com.."},
+ "http://domain.com",
+ true},
+ {{"d1.com", "d2.com", "d3.com", "d4.com", "d5.com", "domain.com.."},
+ "http://domain.com..",
+ true},
+ {{"~d1.com", "~d2.com", "~d3.com", "~d4.com", "~d5.com", "~domain.com."},
+ "http://domain.com",
+ false},
+ {{"~d1.com", "~d2.com", "~d3.com", "~d4.com", "~d5.com", "~domain.com.."},
+ "http://domain.com",
+ false},
+ {{"~d1.com", "~d2.com", "~d3.com", "~d4.com", "~d5.com", "~domain.com.."},
+ "http://sub.domain.com..",
+ false},
+
+ // Short domain patterns.
+ {{"d.de"}, "http://d.de", true},
+ {{"d.de"}, "http://d.de.", true},
+ {{"d.de"}, "http://d.de..", true},
+ {{"~d.de"}, "http://d.de", false},
+ {{"~d.de"}, "http://d.de.", false},
+ {{"~d.de"}, "http://d.de..", false},
+
{{"~domain.com"}, "", true},
{{"~domain.com"}, "http://domain.com", false},
{{"~ddomain.com"}, "http://domain.com", true},
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page