diff options
Diffstat (limited to 'chromium/net/base')
46 files changed, 1336 insertions, 745 deletions
diff --git a/chromium/net/base/address_list.cc b/chromium/net/base/address_list.cc index 7a783a64649..20a6d3d4cc0 100644 --- a/chromium/net/base/address_list.cc +++ b/chromium/net/base/address_list.cc @@ -17,19 +17,17 @@ namespace net { namespace { -std::unique_ptr<base::Value> NetLogAddressListCallback( - const AddressList* address_list, - NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - std::unique_ptr<base::ListValue> list(new base::ListValue()); - - for (auto it = address_list->begin(); it != address_list->end(); ++it) { - list->AppendString(it->ToString()); - } +base::Value NetLogAddressListCallback(const AddressList* address_list, + NetLogCaptureMode capture_mode) { + base::Value dict(base::Value::Type::DICTIONARY); + base::Value list(base::Value::Type::LIST); + + for (const auto& ip_endpoint : *address_list) + list.GetList().emplace_back(ip_endpoint.ToString()); - dict->Set("address_list", std::move(list)); - dict->SetString("canonical_name", address_list->canonical_name()); - return std::move(dict); + dict.SetKey("address_list", std::move(list)); + dict.SetStringKey("canonical_name", address_list->canonical_name()); + return dict; } } // namespace diff --git a/chromium/net/base/auth.cc b/chromium/net/base/auth.cc index 99c02bf0c53..d14a663beaf 100644 --- a/chromium/net/base/auth.cc +++ b/chromium/net/base/auth.cc @@ -11,13 +11,11 @@ AuthChallengeInfo::AuthChallengeInfo() : is_proxy(false) { AuthChallengeInfo::AuthChallengeInfo(const AuthChallengeInfo& other) = default; -bool AuthChallengeInfo::operator==(const AuthChallengeInfo& that) const { - return (is_proxy == that.is_proxy && challenger == that.challenger && - scheme == that.scheme && realm == that.realm); -} - -bool AuthChallengeInfo::operator!=(const AuthChallengeInfo& that) const { - return !(*this == that); +bool AuthChallengeInfo::MatchesExceptPath( + const AuthChallengeInfo& other) const { + return (is_proxy == other.is_proxy && challenger == other.challenger && + scheme == other.scheme && realm == other.realm && + challenge == other.challenge); } AuthChallengeInfo::~AuthChallengeInfo() = default; diff --git a/chromium/net/base/auth.h b/chromium/net/base/auth.h index f206dc26b55..7762d785525 100644 --- a/chromium/net/base/auth.h +++ b/chromium/net/base/auth.h @@ -21,8 +21,10 @@ class NET_EXPORT AuthChallengeInfo { AuthChallengeInfo(const AuthChallengeInfo& other); ~AuthChallengeInfo(); - bool operator==(const AuthChallengeInfo& other) const; - bool operator!=(const AuthChallengeInfo& other) const; + // Returns true if this AuthChallengeInfo is equal to |other| except for + // |path|. Can be used to determine if the same credentials can be provided + // for two different requests. + bool MatchesExceptPath(const AuthChallengeInfo& other) const; // Whether this came from a server or a proxy. bool is_proxy; @@ -36,6 +38,12 @@ class NET_EXPORT AuthChallengeInfo { // The realm of the challenge. May be empty. The encoding is UTF-8. std::string realm; + + // The authentication challenge. + std::string challenge; + + // The path on which authentication was requested. + std::string path; }; // Authentication Credentials for an authentication credentials. diff --git a/chromium/net/base/data_url.cc b/chromium/net/base/data_url.cc index e3c0e360733..90b0bb68647 100644 --- a/chromium/net/base/data_url.cc +++ b/chromium/net/base/data_url.cc @@ -96,25 +96,23 @@ bool DataURL::Parse(const GURL& url, // (Spaces in a data URL should be escaped, which is handled below, so any // spaces now are wrong. People expect to be able to enter them in the URL // bar for text, and it can't hurt, so we allow it.) - std::string temp_data = std::string(comma + 1, end); + // + // TODO(mmenke): Is removing all spaces reasonable? GURL removes trailing + // spaces itself, anyways. Should we just trim leading spaces instead? + // Allowing random intermediary spaces seems unnecessary. + + base::StringPiece raw_body(comma + 1, end); // For base64, we may have url-escaped whitespace which is not part // of the data, and should be stripped. Otherwise, the escaped whitespace // could be part of the payload, so don't strip it. - if (base64_encoded) - UnescapeBinaryURLComponent(temp_data, &temp_data); - - // Strip whitespace. - if (base64_encoded || !(mime_type->compare(0, 5, "text/") == 0 || - mime_type->find("xml") != std::string::npos)) { - base::EraseIf(temp_data, base::IsAsciiWhitespace<wchar_t>); - } + if (base64_encoded) { + std::string unescaped_body = UnescapeBinaryURLComponent(raw_body); - if (!base64_encoded) - UnescapeBinaryURLComponent(temp_data, &temp_data); + // Strip spaces, which aren't allowed in Base64 encoding. + base::EraseIf(unescaped_body, base::IsAsciiWhitespace<char>); - if (base64_encoded) { - size_t length = temp_data.length(); + size_t length = unescaped_body.length(); size_t padding_needed = 4 - (length % 4); // If the input wasn't padded, then we pad it as necessary until we have a // length that is a multiple of 4 as required by our decoder. We don't @@ -122,13 +120,22 @@ bool DataURL::Parse(const GURL& url, // then the input isn't well formed and decoding will fail with or without // padding. if ((padding_needed == 1 || padding_needed == 2) && - temp_data[length - 1] != '=') { - temp_data.resize(length + padding_needed, '='); + unescaped_body[length - 1] != '=') { + unescaped_body.resize(length + padding_needed, '='); } - return base::Base64Decode(temp_data, data); + return base::Base64Decode(unescaped_body, data); + } + + // Strip whitespace for non-text MIME types. + std::string temp; + if (!(mime_type->compare(0, 5, "text/") == 0 || + mime_type->find("xml") != std::string::npos)) { + temp = raw_body.as_string(); + base::EraseIf(temp, base::IsAsciiWhitespace<char>); + raw_body = temp; } - temp_data.swap(*data); + *data = UnescapeBinaryURLComponent(raw_body); return true; } diff --git a/chromium/net/base/directory_lister.cc b/chromium/net/base/directory_lister.cc index bdde8379902..ac4eecbae16 100644 --- a/chromium/net/base/directory_lister.cc +++ b/chromium/net/base/directory_lister.cc @@ -118,9 +118,9 @@ void DirectoryLister::Core::Start() { if (!base::DirectoryExists(dir_)) { origin_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&Core::DoneOnOriginSequence, this, - base::Passed(std::move(directory_list)), - ERR_FILE_NOT_FOUND)); + FROM_HERE, + base::BindOnce(&Core::DoneOnOriginSequence, this, + std::move(directory_list), ERR_FILE_NOT_FOUND)); return; } @@ -167,7 +167,7 @@ void DirectoryLister::Core::Start() { origin_task_runner_->PostTask( FROM_HERE, base::BindOnce(&Core::DoneOnOriginSequence, this, - base::Passed(std::move(directory_list)), OK)); + std::move(directory_list), OK)); } bool DirectoryLister::Core::IsCancelled() const { diff --git a/chromium/net/base/escape.cc b/chromium/net/base/escape.cc index b37078cb968..3521f9e00c9 100644 --- a/chromium/net/base/escape.cc +++ b/chromium/net/base/escape.cc @@ -460,11 +460,6 @@ std::string UnescapeURLComponent(base::StringPiece escaped_text, return UnescapeURLWithAdjustmentsImpl(escaped_text, rules, nullptr); } -base::string16 UnescapeAndDecodeUTF8URLComponent(base::StringPiece text, - UnescapeRule::Type rules) { - return UnescapeAndDecodeUTF8URLComponentWithAdjustments(text, rules, nullptr); -} - base::string16 UnescapeAndDecodeUTF8URLComponentWithAdjustments( base::StringPiece text, UnescapeRule::Type rules, @@ -487,48 +482,68 @@ base::string16 UnescapeAndDecodeUTF8URLComponentWithAdjustments( return base::UTF8ToUTF16WithAdjustments(text, adjustments); } -void UnescapeBinaryURLComponent(const std::string& escaped_text, - UnescapeRule::Type rules, - std::string* unescaped_text) { +std::string UnescapeBinaryURLComponent(base::StringPiece escaped_text, + UnescapeRule::Type rules) { // Only NORMAL and REPLACE_PLUS_WITH_SPACE are supported. DCHECK(rules != UnescapeRule::NONE); DCHECK(!(rules & ~(UnescapeRule::NORMAL | UnescapeRule::REPLACE_PLUS_WITH_SPACE))); + std::string unescaped_text; + // The output of the unescaping is always smaller than the input, so we can // reserve the input size to make sure we have enough buffer and don't have // to allocate in the loop below. // Increase capacity before size, as just resizing can grow capacity // needlessly beyond our requested size. - if (unescaped_text->capacity() < escaped_text.size()) - unescaped_text->reserve(escaped_text.size()); - if (unescaped_text->size() < escaped_text.size()) - unescaped_text->resize(escaped_text.size()); + unescaped_text.reserve(escaped_text.size()); + unescaped_text.resize(escaped_text.size()); size_t output_index = 0; - for (size_t i = 0, max = unescaped_text->size(); i < max;) { + for (size_t i = 0, max = escaped_text.size(); i < max;) { unsigned char byte; // UnescapeUnsignedByteAtIndex does bounds checking, so this is always safe // to call. if (UnescapeUnsignedByteAtIndex(escaped_text, i, &byte)) { - (*unescaped_text)[output_index++] = byte; + unescaped_text[output_index++] = byte; i += 3; continue; } if ((rules & UnescapeRule::REPLACE_PLUS_WITH_SPACE) && escaped_text[i] == '+') { - (*unescaped_text)[output_index++] = ' '; + unescaped_text[output_index++] = ' '; ++i; continue; } - (*unescaped_text)[output_index++] = escaped_text[i++]; + unescaped_text[output_index++] = escaped_text[i++]; + } + + DCHECK_LE(output_index, unescaped_text.size()); + unescaped_text.resize(output_index); + return unescaped_text; +} + +bool UnescapeBinaryURLComponentSafe(base::StringPiece escaped_text, + bool fail_on_path_separators, + std::string* unescaped_text) { + unescaped_text->clear(); + + std::set<unsigned char> illegal_encoded_bytes; + for (char c = '\x00'; c < '\x20'; ++c) { + illegal_encoded_bytes.insert(c); } + if (fail_on_path_separators) { + illegal_encoded_bytes.insert('/'); + illegal_encoded_bytes.insert('\\'); + } + if (ContainsEncodedBytes(escaped_text, illegal_encoded_bytes)) + return false; - DCHECK_LE(output_index, unescaped_text->size()); - unescaped_text->resize(output_index); + *unescaped_text = UnescapeBinaryURLComponent(escaped_text); + return true; } base::string16 UnescapeForHTML(base::StringPiece16 input) { diff --git a/chromium/net/base/escape.h b/chromium/net/base/escape.h index 8e86e61fb47..fc8ce817f06 100644 --- a/chromium/net/base/escape.h +++ b/chromium/net/base/escape.h @@ -135,9 +135,6 @@ NET_EXPORT std::string UnescapeURLComponent(base::StringPiece escaped_text, // be converted into a base::string16 and returned. |adjustments| provides // information on how the original string was adjusted to get the string // returned. -NET_EXPORT base::string16 UnescapeAndDecodeUTF8URLComponent( - base::StringPiece text, - UnescapeRule::Type rules); NET_EXPORT base::string16 UnescapeAndDecodeUTF8URLComponentWithAdjustments( base::StringPiece text, UnescapeRule::Type rules, @@ -149,16 +146,20 @@ NET_EXPORT base::string16 UnescapeAndDecodeUTF8URLComponentWithAdjustments( // be used when displaying the decoded data to the user. // // Only the NORMAL and REPLACE_PLUS_WITH_SPACE rules are allowed. -// |escaped_text| and |unescaped_text| can be the same string. -NET_EXPORT void UnescapeBinaryURLComponent(const std::string& escaped_text, - UnescapeRule::Type rules, - std::string* unescaped_text); -NET_EXPORT inline void UnescapeBinaryURLComponent( - const std::string& escaped_text, - std::string* unescaped_text) { - UnescapeBinaryURLComponent(escaped_text, UnescapeRule::NORMAL, - unescaped_text); -} +NET_EXPORT std::string UnescapeBinaryURLComponent( + base::StringPiece escaped_text, + UnescapeRule::Type rules = UnescapeRule::NORMAL); + +// Variant of UnescapeBinaryURLComponent(). Writes output to |unescaped_text|. +// Returns true on success, returns false and clears |unescaped_text| on +// failure. Fails on characters escaped that are unsafe to unescape in some +// contexts, which are defined as characters "\0" through "\x1F" (Which includes +// CRLF but not space), and optionally path separators. Path separators include +// both forward and backward slashes on all platforms. Does not fail if any of +// those characters appear unescaped in the input string. +NET_EXPORT bool UnescapeBinaryURLComponentSafe(base::StringPiece escaped_text, + bool fail_on_path_separators, + std::string* unescaped_text); // Unescapes the following ampersand character codes from |text|: // < > & " ' diff --git a/chromium/net/base/escape_unittest.cc b/chromium/net/base/escape_unittest.cc index f70f7cd93c4..57be3713769 100644 --- a/chromium/net/base/escape_unittest.cc +++ b/chromium/net/base/escape_unittest.cc @@ -268,7 +268,7 @@ TEST(EscapeTest, UnescapeURLComponent) { EXPECT_EQ(expected, UnescapeURLComponent(input, UnescapeRule::NORMAL)); } -TEST(EscapeTest, UnescapeAndDecodeUTF8URLComponent) { +TEST(EscapeTest, UnescapeAndDecodeUTF8URLComponentWithAdjustments) { const UnescapeAndDecodeCase unescape_cases[] = { { "%", "%", @@ -321,9 +321,11 @@ TEST(EscapeTest, UnescapeAndDecodeUTF8URLComponent) { UnescapeRule::REPLACE_PLUS_WITH_SPACE); EXPECT_EQ(std::string(unescape_case.query_unescaped), unescaped); + // The adjustments argument is covered by the next test. + // // TODO: Need to test unescape_spaces and unescape_percent. - base::string16 decoded = UnescapeAndDecodeUTF8URLComponent( - unescape_case.input, UnescapeRule::NORMAL); + base::string16 decoded = UnescapeAndDecodeUTF8URLComponentWithAdjustments( + unescape_case.input, UnescapeRule::NORMAL, nullptr); EXPECT_EQ(base::WideToUTF16(unescape_case.decoded), decoded); } } @@ -411,13 +413,8 @@ TEST(EscapeTest, UnescapeBinaryURLComponent) { }; for (const auto& test_case : kTestCases) { - std::string output; - UnescapeBinaryURLComponent(test_case.input, test_case.rules, &output); - EXPECT_EQ(std::string(test_case.output), output); - // Also test in-place unescaping. - output = test_case.input; - UnescapeBinaryURLComponent(output, test_case.rules, &output); - EXPECT_EQ(std::string(test_case.output), output); + EXPECT_EQ(test_case.output, + UnescapeBinaryURLComponent(test_case.input, test_case.rules)); } // Test NULL character unescaping, which can't be tested above since those are @@ -430,13 +427,64 @@ TEST(EscapeTest, UnescapeBinaryURLComponent) { expected.push_back(0); expected.push_back(0); expected.append("9Test"); - std::string output; - UnescapeBinaryURLComponent(input, &output); - EXPECT_EQ(expected, output); - // Also test in-place unescaping. - output = input; - UnescapeBinaryURLComponent(output, &output); - EXPECT_EQ(expected, output); + EXPECT_EQ(expected, UnescapeBinaryURLComponent(input)); +} + +TEST(EscapeTest, UnescapeBinaryURLComponentSafe) { + const struct TestCase { + const char* input; + // Expected output. Null if call is expected to fail when + // |fail_on_path_separators| is false. + const char* expected_output; + // Whether |input| has any escaped path separators. + bool has_path_separators; + } kTestCases[] = { + // Spaces, percents, and invalid UTF-8 characters are all successfully + // unescaped. + {"%20%25foo%81", " %foo\x81", false}, + + // Characters disallowed unconditionally. + {"foo%00", nullptr, false}, + {"foo%01", nullptr, false}, + {"foo%0A", nullptr, false}, + {"foo%0D", nullptr, false}, + + // Path separators. + {"foo%2F", "foo/", true}, + {"foo%5C", "foo\\", true}, + + // Characters that are considered invalid to escape are ignored if passed + // in unescaped. + {"foo\x01\r/\\", "foo\x01\r/\\", false}, + }; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(test_case.input); + + std::string output = "foo"; + if (!test_case.expected_output) { + EXPECT_FALSE(UnescapeBinaryURLComponentSafe( + test_case.input, false /* fail_on_path_separators */, &output)); + EXPECT_TRUE(output.empty()); + EXPECT_FALSE(UnescapeBinaryURLComponentSafe( + test_case.input, true /* fail_on_path_separators */, &output)); + EXPECT_TRUE(output.empty()); + continue; + } + EXPECT_TRUE(UnescapeBinaryURLComponentSafe( + test_case.input, false /* fail_on_path_separators */, &output)); + EXPECT_EQ(test_case.expected_output, output); + if (test_case.has_path_separators) { + EXPECT_FALSE(UnescapeBinaryURLComponentSafe( + test_case.input, true /* fail_on_path_separators */, &output)); + EXPECT_TRUE(output.empty()); + } else { + output = "foo"; + EXPECT_TRUE(UnescapeBinaryURLComponentSafe( + test_case.input, true /* fail_on_path_separators */, &output)); + EXPECT_EQ(test_case.expected_output, output); + } + } } TEST(EscapeTest, EscapeForHTML) { diff --git a/chromium/net/base/features.cc b/chromium/net/base/features.cc index 2fcae58be15..ae53c907147 100644 --- a/chromium/net/base/features.cc +++ b/chromium/net/base/features.cc @@ -7,6 +7,16 @@ namespace net { namespace features { +// Toggles the `Accept-Language` HTTP request header, which +// https://github.com/WICG/lang-client-hint proposes that we deprecate. +const base::Feature kAcceptLanguageHeader{"AcceptLanguageHeader", + base::FEATURE_ENABLED_BY_DEFAULT}; + +const base::Feature kCapRefererHeaderLength = { + "CapRefererHeaderLength", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::FeatureParam<int> kMaxRefererHeaderLength = { + &kCapRefererHeaderLength, "MaxRefererHeaderLength", 4096}; + // Uses a site isolated code cache that is keyed on the resource url and the // origin lock of the renderer that is requesting the resource. The requests // to site-isolated code cache are handled by the content/GeneratedCodeCache @@ -22,12 +32,19 @@ const base::Feature kIsolatedCodeCache = {"IsolatedCodeCache", const base::Feature kEnforceTLS13Downgrade{"EnforceTLS13Downgrade", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kEnableTLS13EarlyData{"EnableTLS13EarlyData", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kNetworkQualityEstimator{"NetworkQualityEstimator", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kSplitCacheByTopFrameOrigin{ "SplitCacheByTopFrameOrigin", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPartitionConnectionsByNetworkIsolationKey{ + "PartitionConnectionsByNetworkIsolationKey", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kTLS13KeyUpdate{"TLS13KeyUpdate", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -40,5 +57,8 @@ const base::Feature kNetUnusedIdleSocketTimeout{ const base::Feature kSameSiteByDefaultCookies{ "SameSiteByDefaultCookies", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCookiesWithoutSameSiteMustBeSecure{ + "CookiesWithoutSameSiteMustBeSecure", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace features } // namespace net diff --git a/chromium/net/base/features.h b/chromium/net/base/features.h index 1069c09722c..00856023cc4 100644 --- a/chromium/net/base/features.h +++ b/chromium/net/base/features.h @@ -6,11 +6,21 @@ #define NET_BASE_FEATURES_H_ #include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" #include "net/base/net_export.h" namespace net { namespace features { +// Toggles the `Accept-Language` HTTP request header, which +// https://github.com/WICG/lang-client-hint proposes that we deprecate. +NET_EXPORT extern const base::Feature kAcceptLanguageHeader; + +// Caps the length of the `referer` header to 4k, which should be enough for +// anyone. +NET_EXPORT extern const base::Feature kCapRefererHeaderLength; +NET_EXPORT extern const base::FeatureParam<int> kMaxRefererHeaderLength; + // Uses a site isolated code cache that is keyed on the resource url and the // origin lock of the renderer that is requesting the resource. The requests // to site-isolated code cache are handled by the content/GeneratedCodeCache @@ -24,6 +34,9 @@ NET_EXPORT extern const base::Feature kIsolatedCodeCache; // with some buggy non-compliant TLS-terminating proxies. NET_EXPORT extern const base::Feature kEnforceTLS13Downgrade; +// Enables TLS 1.3 early data. +NET_EXPORT extern const base::Feature kEnableTLS13EarlyData; + // Enables optimizing the network quality estimation algorithms in network // quality estimator (NQE). NET_EXPORT extern const base::Feature kNetworkQualityEstimator; @@ -31,6 +44,11 @@ NET_EXPORT extern const base::Feature kNetworkQualityEstimator; // Splits cache entries by the request's top frame's origin if one is available. NET_EXPORT extern const base::Feature kSplitCacheByTopFrameOrigin; +// Partitions connections based on the NetworkIsolationKey associated with a +// request. +NET_EXPORT extern const base::Feature + kPartitionConnectionsByNetworkIsolationKey; + // Enables sending TLS 1.3 Key Update messages on TLS 1.3 connections in order // to ensure that this corner of the spec is exercised. This is currently // disabled by default because we discovered incompatibilities with some @@ -41,8 +59,7 @@ NET_EXPORT extern const base::Feature kTLS13KeyUpdate; NET_EXPORT extern const base::Feature kPostQuantumCECPQ2; // Changes the timeout after which unused sockets idle sockets are cleaned up. -NET_EXPORT -extern const base::Feature kNetUnusedIdleSocketTimeout; +NET_EXPORT extern const base::Feature kNetUnusedIdleSocketTimeout; // When enabled, makes cookies without a SameSite attribute behave like // SameSite=Lax cookies by default, and requires SameSite=None to be specified @@ -51,6 +68,12 @@ extern const base::Feature kNetUnusedIdleSocketTimeout; // restriction, i.e., available in a third-party context. NET_EXPORT extern const base::Feature kSameSiteByDefaultCookies; +// When enabled, cookies without SameSite restrictions that don't specify the +// Secure attribute will be rejected if set from an insecure context, or treated +// as secure if set from a secure context. This ONLY has an effect if +// SameSiteByDefaultCookies is also enabled. +NET_EXPORT extern const base::Feature kCookiesWithoutSameSiteMustBeSecure; + } // namespace features } // namespace net diff --git a/chromium/net/base/filename_util.cc b/chromium/net/base/filename_util.cc index a2bfb499547..a3135f1ed85 100644 --- a/chromium/net/base/filename_util.cc +++ b/chromium/net/base/filename_util.cc @@ -120,7 +120,7 @@ bool FileURLToFilePath(const GURL& url, base::FilePath* file_path) { // Unescape all percent-encoded sequences, including blacklisted-for-display // characters, control characters and invalid UTF-8 byte sequences. // Percent-encoded bytes are not meaningful in a file system. - UnescapeBinaryURLComponent(path, &path); + path = UnescapeBinaryURLComponent(path); #if defined(OS_WIN) if (base::IsStringUTF8(path)) { diff --git a/chromium/net/base/filename_util_internal.cc b/chromium/net/base/filename_util_internal.cc index e937a8be799..46dc33aaaf8 100644 --- a/chromium/net/base/filename_util_internal.cc +++ b/chromium/net/base/filename_util_internal.cc @@ -125,9 +125,8 @@ std::string GetFileNameFromURL(const GURL& url, if (!url.is_valid() || url.SchemeIs("about") || url.SchemeIs("data")) return std::string(); - std::string unescaped_url_filename; - UnescapeBinaryURLComponent(url.ExtractFileName(), UnescapeRule::NORMAL, - &unescaped_url_filename); + std::string unescaped_url_filename = + UnescapeBinaryURLComponent(url.ExtractFileName(), UnescapeRule::NORMAL); // The URL's path should be escaped UTF-8, but may not be. std::string decoded_filename = unescaped_url_filename; diff --git a/chromium/net/base/ip_endpoint.cc b/chromium/net/base/ip_endpoint.cc index b3866b915f4..e6115c41325 100644 --- a/chromium/net/base/ip_endpoint.cc +++ b/chromium/net/base/ip_endpoint.cc @@ -181,4 +181,8 @@ bool IPEndPoint::operator==(const IPEndPoint& other) const { return address_ == other.address_ && port_ == other.port_; } +bool IPEndPoint::operator!=(const IPEndPoint& that) const { + return !(*this == that); +} + } // namespace net diff --git a/chromium/net/base/ip_endpoint.h b/chromium/net/base/ip_endpoint.h index f7bb248fd4c..fd635b62432 100644 --- a/chromium/net/base/ip_endpoint.h +++ b/chromium/net/base/ip_endpoint.h @@ -65,6 +65,7 @@ class NET_EXPORT IPEndPoint { bool operator<(const IPEndPoint& that) const; bool operator==(const IPEndPoint& that) const; + bool operator!=(const IPEndPoint& that) const; private: IPAddress address_; diff --git a/chromium/net/base/linked_hash_map.h b/chromium/net/base/linked_hash_map.h deleted file mode 100644 index 921764f79c6..00000000000 --- a/chromium/net/base/linked_hash_map.h +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This is a simplistic insertion-ordered map. It behaves similarly to an STL -// map, but only implements a small subset of the map's methods. Internally, we -// just keep a map and a list going in parallel. -// -// This class provides no thread safety guarantees, beyond what you would -// normally see with std::list. -// -// Iterators should be stable in the face of mutations, except for an -// iterator pointing to an element that was just deleted. - -#ifndef NET_BASE_LINKED_HASH_MAP_H_ -#define NET_BASE_LINKED_HASH_MAP_H_ - -#include <stddef.h> - -#include <list> -#include <unordered_map> -#include <utility> - -#include "base/logging.h" -#include "base/macros.h" - -namespace net { - -// This holds a list of pair<Key, Value> items. This list is what gets -// traversed, and it's iterators from this list that we return from -// begin/end/find. -// -// We also keep a map<Key, list::iterator> for find. Since std::list is a -// doubly-linked list, the iterators should remain stable. -template <class Key, class Value, class Hash = std::hash<Key>> -class linked_hash_map { - private: - typedef std::list<std::pair<Key, Value> > ListType; - typedef std::unordered_map<Key, typename ListType::iterator, Hash> MapType; - - public: - typedef typename ListType::iterator iterator; - typedef typename ListType::reverse_iterator reverse_iterator; - typedef typename ListType::const_iterator const_iterator; - typedef typename ListType::const_reverse_iterator const_reverse_iterator; - typedef typename MapType::key_type key_type; - typedef typename ListType::value_type value_type; - typedef typename ListType::size_type size_type; - - linked_hash_map() = default; - explicit linked_hash_map(size_type bucket_count) : map_(bucket_count) {} - - linked_hash_map(linked_hash_map&& other) = default; - linked_hash_map& operator=(linked_hash_map&& other) = default; - - // Returns an iterator to the first (insertion-ordered) element. Like a map, - // this can be dereferenced to a pair<Key, Value>. - iterator begin() { - return list_.begin(); - } - const_iterator begin() const { - return list_.begin(); - } - - // Returns an iterator beyond the last element. - iterator end() { - return list_.end(); - } - const_iterator end() const { - return list_.end(); - } - - // Returns an iterator to the last (insertion-ordered) element. Like a map, - // this can be dereferenced to a pair<Key, Value>. - reverse_iterator rbegin() { - return list_.rbegin(); - } - const_reverse_iterator rbegin() const { - return list_.rbegin(); - } - - // Returns an iterator beyond the first element. - reverse_iterator rend() { - return list_.rend(); - } - const_reverse_iterator rend() const { - return list_.rend(); - } - - // Front and back accessors common to many stl containers. - - // Returns the earliest-inserted element - const value_type& front() const { - return list_.front(); - } - - // Returns the earliest-inserted element. - value_type& front() { - return list_.front(); - } - - // Returns the most-recently-inserted element. - const value_type& back() const { - return list_.back(); - } - - // Returns the most-recently-inserted element. - value_type& back() { - return list_.back(); - } - - // Clears the map of all values. - void clear() { - map_.clear(); - list_.clear(); - } - - // Returns true iff the map is empty. - bool empty() const { - return list_.empty(); - } - - // Removes the first element from the list. - void pop_front() { erase(begin()); } - - // Erases values with the provided key. Returns the number of elements - // erased. In this implementation, this will be 0 or 1. - size_type erase(const Key& key) { - typename MapType::iterator found = map_.find(key); - if (found == map_.end()) return 0; - - list_.erase(found->second); - map_.erase(found); - - return 1; - } - - // Erases the item that 'position' points to. Returns an iterator that points - // to the item that comes immediately after the deleted item in the list, or - // end(). - // If the provided iterator is invalid or there is inconsistency between the - // map and list, a CHECK() error will occur. - iterator erase(iterator position) { - typename MapType::iterator found = map_.find(position->first); - CHECK(found->second == position) - << "Inconsisent iterator for map and list, or the iterator is invalid."; - - map_.erase(found); - return list_.erase(position); - } - - // Erases all the items in the range [first, last). Returns an iterator that - // points to the item that comes immediately after the last deleted item in - // the list, or end(). - iterator erase(iterator first, iterator last) { - while (first != last && first != end()) { - first = erase(first); - } - return first; - } - - // Finds the element with the given key. Returns an iterator to the - // value found, or to end() if the value was not found. Like a map, this - // iterator points to a pair<Key, Value>. - iterator find(const Key& key) { - typename MapType::iterator found = map_.find(key); - if (found == map_.end()) { - return end(); - } - return found->second; - } - - const_iterator find(const Key& key) const { - typename MapType::const_iterator found = map_.find(key); - if (found == map_.end()) { - return end(); - } - return found->second; - } - - // Returns the bounds of a range that includes all the elements in the - // container with a key that compares equal to x. - std::pair<iterator, iterator> equal_range(const key_type& key) { - std::pair<typename MapType::iterator, typename MapType::iterator> eq_range = - map_.equal_range(key); - - return std::make_pair(eq_range.first->second, eq_range.second->second); - } - - std::pair<const_iterator, const_iterator> equal_range( - const key_type& key) const { - std::pair<typename MapType::const_iterator, - typename MapType::const_iterator> eq_range = - map_.equal_range(key); - const const_iterator& start_iter = eq_range.first != map_.end() ? - eq_range.first->second : end(); - const const_iterator& end_iter = eq_range.second != map_.end() ? - eq_range.second->second : end(); - - return std::make_pair(start_iter, end_iter); - } - - // Returns the value mapped to key, or an inserted iterator to that position - // in the map. - Value& operator[](const key_type& key) { - return (*((this->insert(std::make_pair(key, Value()))).first)).second; - } - - // Inserts an element into the map - std::pair<iterator, bool> insert(const std::pair<Key, Value>& pair) { - // First make sure the map doesn't have a key with this value. If it does, - // return a pair with an iterator to it, and false indicating that we - // didn't insert anything. - typename MapType::iterator found = map_.find(pair.first); - if (found != map_.end()) return std::make_pair(found->second, false); - - // Otherwise, insert into the list first. - list_.push_back(pair); - - // Obtain an iterator to the newly added element. We do -- instead of - - // since list::iterator doesn't implement operator-(). - typename ListType::iterator last = list_.end(); - --last; - - CHECK(map_.insert(std::make_pair(pair.first, last)).second) - << "Map and list are inconsistent"; - - return std::make_pair(last, true); - } - - size_type size() const { - return list_.size(); - } - - template <typename... Args> - std::pair<iterator, bool> emplace(Args&&... args) { - ListType node_donor; - auto node_pos = - node_donor.emplace(node_donor.end(), std::forward<Args>(args)...); - const auto& k = node_pos->first; - auto ins = map_.insert({k, node_pos}); - if (!ins.second) - return {ins.first->second, false}; - list_.splice(list_.end(), node_donor, node_pos); - return {ins.first->second, true}; - } - - void swap(linked_hash_map& other) { - map_.swap(other.map_); - list_.swap(other.list_); - } - - private: - // The map component, used for speedy lookups - MapType map_; - - // The list component, used for maintaining insertion order - ListType list_; - - // |map_| contains iterators to |list_|, therefore a default copy constructor - // or copy assignment operator would result in an inconsistent state. - DISALLOW_COPY_AND_ASSIGN(linked_hash_map); -}; - -} // namespace net - -#endif // NET_BASE_LINKED_HASH_MAP_H_ diff --git a/chromium/net/base/logging_network_change_observer.cc b/chromium/net/base/logging_network_change_observer.cc index 4d91df37ffa..5ca13b70189 100644 --- a/chromium/net/base/logging_network_change_observer.cc +++ b/chromium/net/base/logging_network_change_observer.cc @@ -38,29 +38,28 @@ int HumanReadableNetworkHandle(NetworkChangeNotifier::NetworkHandle network) { // Return a dictionary of values that provide information about a // network-specific change. This also includes relevant current state // like the default network, and the types of active networks. -std::unique_ptr<base::Value> NetworkSpecificNetLogCallback( +base::Value NetworkSpecificNetLogCallback( NetworkChangeNotifier::NetworkHandle network, NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetInteger("changed_network_handle", - HumanReadableNetworkHandle(network)); - dict->SetString( + base::Value dict(base::Value::Type::DICTIONARY); + dict.SetIntKey("changed_network_handle", HumanReadableNetworkHandle(network)); + dict.SetStringKey( "changed_network_type", NetworkChangeNotifier::ConnectionTypeToString( NetworkChangeNotifier::GetNetworkConnectionType(network))); - dict->SetInteger( + dict.SetIntKey( "default_active_network_handle", HumanReadableNetworkHandle(NetworkChangeNotifier::GetDefaultNetwork())); NetworkChangeNotifier::NetworkList networks; NetworkChangeNotifier::GetConnectedNetworks(&networks); for (NetworkChangeNotifier::NetworkHandle active_network : networks) { - dict->SetString( + dict.SetStringKey( "current_active_networks." + base::NumberToString(HumanReadableNetworkHandle(active_network)), NetworkChangeNotifier::ConnectionTypeToString( NetworkChangeNotifier::GetNetworkConnectionType(active_network))); } - return std::move(dict); + return dict; } } // namespace diff --git a/chromium/net/base/net_error_list.h b/chromium/net/base/net_error_list.h index 7fe82d958bc..9614b3d857d 100644 --- a/chromium/net/base/net_error_list.h +++ b/chromium/net/base/net_error_list.h @@ -4,8 +4,9 @@ // This file intentionally does not have header guards, it's included // inside a macro to generate enum values. The following line silences a -// presubmit warning that would otherwise be triggered by this: +// presubmit and Tricium warning that would otherwise be triggered by this: // no-include-guard-because-multiply-included +// NOLINT(build/header_guard) // This file contains the list of network errors. @@ -281,8 +282,7 @@ NET_ERROR(SSL_CLIENT_AUTH_SIGNATURE_FAILED, -141) // which exceeds size threshold). NET_ERROR(MSG_TOO_BIG, -142) -// A SPDY session already exists, and should be used instead of this connection. -NET_ERROR(SPDY_SESSION_ALREADY_EXISTS, -143) +// Error -143 was removed (SPDY_SESSION_ALREADY_EXISTS) // Error -144 was removed (LIMIT_VIOLATION). @@ -395,19 +395,7 @@ NET_ERROR(WS_UPGRADE, -173) // visible, because the normal Read() method is used as a fallback. NET_ERROR(READ_IF_READY_NOT_IMPLEMENTED, -174) -// This error is emitted if TLS 1.3 is enabled, connecting with it failed, but -// retrying at a downgraded maximum version succeeded. This could mean: -// -// 1. This is a transient network error that will be resolved when the user -// reloads. -// -// 2. The user is behind a buggy network middlebox, firewall, or proxy which is -// interfering with TLS 1.3. -// -// 3. The server is buggy and does not implement TLS version negotiation -// correctly. TLS 1.3 was tweaked to avoid a common server bug here, so this -// is unlikely. -NET_ERROR(SSL_VERSION_INTERFERENCE, -175) +// Error -175 was removed (SSL_VERSION_INTERFERENCE). // No socket buffer space is available. NET_ERROR(NO_BUFFER_SPACE, -176) diff --git a/chromium/net/base/net_errors.cc b/chromium/net/base/net_errors.cc index ed7f9fb73ce..ed6bc451471 100644 --- a/chromium/net/base/net_errors.cc +++ b/chromium/net/base/net_errors.cc @@ -22,7 +22,7 @@ std::string ExtendedErrorToString(int error, int extended_error_code) { } std::string ErrorToShortString(int error) { - if (error == 0) + if (error == OK) return "OK"; const char* error_string; diff --git a/chromium/net/base/net_errors.h b/chromium/net/base/net_errors.h index 489c5e22978..f24540a9738 100644 --- a/chromium/net/base/net_errors.h +++ b/chromium/net/base/net_errors.h @@ -16,7 +16,7 @@ namespace net { // Error values are negative. enum Error { - // No error. + // No error. Change NetError.template after changing value. OK = 0, #define NET_ERROR(label, value) ERR_ ## label = value, diff --git a/chromium/net/base/net_string_util.h b/chromium/net/base/net_string_util.h index fb9c0e15b13..e1ba4303fc7 100644 --- a/chromium/net/base/net_string_util.h +++ b/chromium/net/base/net_string_util.h @@ -8,6 +8,7 @@ #include <string> #include "base/strings/string16.h" +#include "base/strings/string_piece_forward.h" #include "net/base/net_export.h" // String conversion functions. By default, they're implemented with ICU, but @@ -19,28 +20,31 @@ extern const char* const kCharsetLatin1; // Converts |text| using |charset| to UTF-8, and writes it to |output|. // On failure, returns false and |output| is cleared. -bool ConvertToUtf8(const std::string& text, const char* charset, +bool ConvertToUtf8(base::StringPiece text, + const char* charset, std::string* output); // Converts |text| using |charset| to UTF-8, normalizes the result, and writes // it to |output|. On failure, returns false and |output| is cleared. -bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset, +bool ConvertToUtf8AndNormalize(base::StringPiece text, + const char* charset, std::string* output); // Converts |text| using |charset| to UTF-16, and writes it to |output|. // On failure, returns false and |output| is cleared. -bool ConvertToUTF16(const std::string& text, const char* charset, +bool ConvertToUTF16(base::StringPiece text, + const char* charset, base::string16* output); // Converts |text| using |charset| to UTF-16, and writes it to |output|. // Any characters that can not be converted are replaced with U+FFFD. -bool ConvertToUTF16WithSubstitutions(const std::string& text, +bool ConvertToUTF16WithSubstitutions(base::StringPiece text, const char* charset, base::string16* output); // Converts |str| to uppercase using the default locale, and writes it to // |output|. On failure returns false and |output| is cleared. -NET_EXPORT_PRIVATE bool ToUpper(const base::string16& str, +NET_EXPORT_PRIVATE bool ToUpper(base::StringPiece16 str, base::string16* output); } // namespace net diff --git a/chromium/net/base/net_string_util_icu.cc b/chromium/net/base/net_string_util_icu.cc index 7a3e96b5453..c3ef1367992 100644 --- a/chromium/net/base/net_string_util_icu.cc +++ b/chromium/net/base/net_string_util_icu.cc @@ -7,6 +7,7 @@ #include "base/i18n/case_conversion.h" #include "base/i18n/i18n_constants.h" #include "base/i18n/icu_string_conversions.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "third_party/icu/source/common/unicode/ucnv.h" @@ -14,7 +15,8 @@ namespace net { const char* const kCharsetLatin1 = base::kCodepageLatin1; -bool ConvertToUtf8(const std::string& text, const char* charset, +bool ConvertToUtf8(base::StringPiece text, + const char* charset, std::string* output) { output->clear(); @@ -41,26 +43,27 @@ bool ConvertToUtf8(const std::string& text, const char* charset, return true; } -bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset, +bool ConvertToUtf8AndNormalize(base::StringPiece text, + const char* charset, std::string* output) { - return base::ConvertToUtf8AndNormalize(text, charset, output); + return base::ConvertToUtf8AndNormalize(text, charset, output); } -bool ConvertToUTF16(const std::string& text, const char* charset, +bool ConvertToUTF16(base::StringPiece text, + const char* charset, base::string16* output) { return base::CodepageToUTF16(text, charset, base::OnStringConversionError::FAIL, output); } -bool ConvertToUTF16WithSubstitutions(const std::string& text, +bool ConvertToUTF16WithSubstitutions(base::StringPiece text, const char* charset, base::string16* output) { - return base::CodepageToUTF16(text, charset, - base::OnStringConversionError::SUBSTITUTE, - output); + return base::CodepageToUTF16( + text, charset, base::OnStringConversionError::SUBSTITUTE, output); } -bool ToUpper(const base::string16& str, base::string16* output) { +bool ToUpper(base::StringPiece16 str, base::string16* output) { *output = base::i18n::ToUpper(str); return true; } diff --git a/chromium/net/base/net_string_util_icu_alternatives_android.cc b/chromium/net/base/net_string_util_icu_alternatives_android.cc index 736f41fd373..222312e18f5 100644 --- a/chromium/net/base/net_string_util_icu_alternatives_android.cc +++ b/chromium/net/base/net_string_util_icu_alternatives_android.cc @@ -17,7 +17,7 @@ namespace { // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode // string). Returns the result jstring, or NULL on failure. -ScopedJavaLocalRef<jstring> ConvertToJstring(const std::string& text, +ScopedJavaLocalRef<jstring> ConvertToJstring(base::StringPiece text, const char* charset) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> java_byte_buffer( @@ -34,8 +34,8 @@ ScopedJavaLocalRef<jstring> ConvertToJstring(const std::string& text, // Attempts to convert |text| encoded in |charset| to a jstring (Java unicode // string) and then normalizes the string. Returns the result jstring, or NULL // on failure. -ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring( - const std::string& text, const char* charset) { +ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring(base::StringPiece text, + const char* charset) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> java_byte_buffer( env, @@ -51,7 +51,8 @@ ScopedJavaLocalRef<jstring> ConvertToNormalizedJstring( // Converts |text| encoded in |charset| to a jstring (Java unicode string). // Any characters that can not be converted are replaced with U+FFFD. ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions( - const std::string& text, const char* charset) { + base::StringPiece text, + const char* charset) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> java_byte_buffer( env, @@ -70,7 +71,8 @@ ScopedJavaLocalRef<jstring> ConvertToJstringWithSubstitutions( // by base::kCodepageLatin1 (which is const char[]) in net_string_util_icu.cc. const char* const kCharsetLatin1 = "ISO-8859-1"; -bool ConvertToUtf8(const std::string& text, const char* charset, +bool ConvertToUtf8(base::StringPiece text, + const char* charset, std::string* output) { output->clear(); ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset); @@ -80,7 +82,8 @@ bool ConvertToUtf8(const std::string& text, const char* charset, return true; } -bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset, +bool ConvertToUtf8AndNormalize(base::StringPiece text, + const char* charset, std::string* output) { output->clear(); ScopedJavaLocalRef<jstring> java_result = ConvertToNormalizedJstring( @@ -91,7 +94,8 @@ bool ConvertToUtf8AndNormalize(const std::string& text, const char* charset, return true; } -bool ConvertToUTF16(const std::string& text, const char* charset, +bool ConvertToUTF16(base::StringPiece text, + const char* charset, base::string16* output) { output->clear(); ScopedJavaLocalRef<jstring> java_result = ConvertToJstring(text, charset); @@ -101,19 +105,19 @@ bool ConvertToUTF16(const std::string& text, const char* charset, return true; } -bool ConvertToUTF16WithSubstitutions(const std::string& text, +bool ConvertToUTF16WithSubstitutions(base::StringPiece text, const char* charset, base::string16* output) { output->clear(); ScopedJavaLocalRef<jstring> java_result = - ConvertToJstringWithSubstitutions(text, charset); + ConvertToJstringWithSubstitutions(text, charset); if (java_result.is_null()) return false; *output = base::android::ConvertJavaStringToUTF16(java_result); return true; } -bool ToUpper(const base::string16& str, base::string16* output) { +bool ToUpper(base::StringPiece16 str, base::string16* output) { output->clear(); JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jstring> java_new_str( diff --git a/chromium/net/base/net_string_util_icu_alternatives_ios.mm b/chromium/net/base/net_string_util_icu_alternatives_ios.mm index 09384344881..5cc54f67907 100644 --- a/chromium/net/base/net_string_util_icu_alternatives_ios.mm +++ b/chromium/net/base/net_string_util_icu_alternatives_ios.mm @@ -35,7 +35,7 @@ bool CharsetToCFStringEncoding(const char* charset, // by base::kCodepageLatin1 (which is const char[]) in net_string_util_icu.cc. const char* const kCharsetLatin1 = "ISO-8859-1"; -bool ConvertToUtf8(const std::string& text, +bool ConvertToUtf8(base::StringPiece text, const char* charset, std::string* output) { CFStringEncoding encoding; @@ -52,28 +52,28 @@ bool ConvertToUtf8(const std::string& text, return true; } -bool ConvertToUtf8AndNormalize(const std::string& text, +bool ConvertToUtf8AndNormalize(base::StringPiece text, const char* charset, std::string* output) { DCHECK(false) << "Not implemented yet."; return false; } -bool ConvertToUTF16(const std::string& text, +bool ConvertToUTF16(base::StringPiece text, const char* charset, base::string16* output) { DCHECK(false) << "Not implemented yet."; return false; } -bool ConvertToUTF16WithSubstitutions(const std::string& text, +bool ConvertToUTF16WithSubstitutions(base::StringPiece text, const char* charset, base::string16* output) { DCHECK(false) << "Not implemented yet."; return false; } -bool ToUpper(const base::string16& str, base::string16* output) { +bool ToUpper(base::StringPiece16 str, base::string16* output) { base::ScopedCFTypeRef<CFStringRef> cfstring(base::SysUTF16ToCFStringRef(str)); base::ScopedCFTypeRef<CFMutableStringRef> mutable_cfstring( CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfstring.get())); diff --git a/chromium/net/base/network_change_notifier.cc b/chromium/net/base/network_change_notifier.cc index 1fca77839dc..48fb8504ff5 100644 --- a/chromium/net/base/network_change_notifier.cc +++ b/chromium/net/base/network_change_notifier.cc @@ -8,6 +8,7 @@ #include <unordered_set> #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/synchronization/lock.h" @@ -62,10 +63,10 @@ const NetworkChangeNotifier::NetworkHandle NetworkChangeNotifier::kInvalidNetworkHandle = -1; // NetworkState is thread safe. -class NetworkChangeNotifier::NetworkState { +class NetworkChangeNotifier::NetworkState + : public base::RefCountedThreadSafe<NetworkChangeNotifier::NetworkState> { public: NetworkState() = default; - ~NetworkState() = default; void GetDnsConfig(DnsConfig* config) const { base::AutoLock lock(lock_); @@ -86,6 +87,9 @@ class NetworkChangeNotifier::NetworkState { } private: + friend class base::RefCountedThreadSafe<NetworkState>; + ~NetworkState() = default; + mutable base::Lock lock_; DnsConfig dns_config_; bool set_ = false; @@ -114,7 +118,6 @@ class NetworkChangeNotifier::NetworkChangeCalculator ~NetworkChangeCalculator() override { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(g_network_change_notifier); RemoveConnectionTypeObserver(this); RemoveIPAddressObserver(this); } @@ -174,10 +177,17 @@ class NetworkChangeNotifier::NetworkChangeCalculator DISALLOW_COPY_AND_ASSIGN(NetworkChangeCalculator); }; +void NetworkChangeNotifier::ClearGlobalPointer() { + if (!cleared_global_pointer_) { + cleared_global_pointer_ = true; + DCHECK_EQ(this, g_network_change_notifier); + g_network_change_notifier = nullptr; + } +} + NetworkChangeNotifier::~NetworkChangeNotifier() { network_change_calculator_.reset(); - DCHECK_EQ(this, g_network_change_notifier); - g_network_change_notifier = nullptr; + ClearGlobalPointer(); } // static @@ -373,7 +383,9 @@ void NetworkChangeNotifier::GetDnsConfig(DnsConfig* config) { if (!g_network_change_notifier) { *config = DnsConfig(); } else { - g_network_change_notifier->network_state_->GetDnsConfig(config); + scoped_refptr<NetworkState> network_state = + g_network_change_notifier->network_state_; + network_state->GetDnsConfig(config); } } @@ -483,92 +495,122 @@ NetworkChangeNotifier* NetworkChangeNotifier::CreateMock() { return new MockNetworkChangeNotifier(); } +NetworkChangeNotifier::IPAddressObserver::IPAddressObserver() = default; +NetworkChangeNotifier::IPAddressObserver::~IPAddressObserver() = default; + +NetworkChangeNotifier::ConnectionTypeObserver::ConnectionTypeObserver() = + default; +NetworkChangeNotifier::ConnectionTypeObserver::~ConnectionTypeObserver() = + default; + +NetworkChangeNotifier::DNSObserver::DNSObserver() = default; +NetworkChangeNotifier::DNSObserver::~DNSObserver() = default; + +NetworkChangeNotifier::NetworkChangeObserver::NetworkChangeObserver() = default; +NetworkChangeNotifier::NetworkChangeObserver::~NetworkChangeObserver() = + default; + +NetworkChangeNotifier::MaxBandwidthObserver::MaxBandwidthObserver() = default; +NetworkChangeNotifier::MaxBandwidthObserver::~MaxBandwidthObserver() = default; + +NetworkChangeNotifier::NetworkObserver::NetworkObserver() = default; +NetworkChangeNotifier::NetworkObserver::~NetworkObserver() = default; + void NetworkChangeNotifier::AddIPAddressObserver(IPAddressObserver* observer) { - if (g_network_change_notifier) - g_network_change_notifier->ip_address_observer_list_->AddObserver(observer); + if (g_network_change_notifier) { + observer->observer_list_ = + g_network_change_notifier->ip_address_observer_list_; + observer->observer_list_->AddObserver(observer); + } } void NetworkChangeNotifier::AddConnectionTypeObserver( ConnectionTypeObserver* observer) { if (g_network_change_notifier) { - g_network_change_notifier->connection_type_observer_list_->AddObserver( - observer); + observer->observer_list_ = + g_network_change_notifier->connection_type_observer_list_; + observer->observer_list_->AddObserver(observer); } } void NetworkChangeNotifier::AddDNSObserver(DNSObserver* observer) { if (g_network_change_notifier) { - g_network_change_notifier->resolver_state_observer_list_->AddObserver( - observer); + observer->observer_list_ = + g_network_change_notifier->resolver_state_observer_list_; + observer->observer_list_->AddObserver(observer); } } void NetworkChangeNotifier::AddNetworkChangeObserver( NetworkChangeObserver* observer) { if (g_network_change_notifier) { - g_network_change_notifier->network_change_observer_list_->AddObserver( - observer); + observer->observer_list_ = + g_network_change_notifier->network_change_observer_list_; + observer->observer_list_->AddObserver(observer); } } void NetworkChangeNotifier::AddMaxBandwidthObserver( MaxBandwidthObserver* observer) { if (g_network_change_notifier) { - g_network_change_notifier->max_bandwidth_observer_list_->AddObserver( - observer); + observer->observer_list_ = + g_network_change_notifier->max_bandwidth_observer_list_; + observer->observer_list_->AddObserver(observer); } } void NetworkChangeNotifier::AddNetworkObserver(NetworkObserver* observer) { DCHECK(AreNetworkHandlesSupported()); if (g_network_change_notifier) { - g_network_change_notifier->network_observer_list_->AddObserver(observer); + observer->observer_list_ = + g_network_change_notifier->network_observer_list_; + observer->observer_list_->AddObserver(observer); } } void NetworkChangeNotifier::RemoveIPAddressObserver( IPAddressObserver* observer) { - if (g_network_change_notifier) { - g_network_change_notifier->ip_address_observer_list_->RemoveObserver( - observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } void NetworkChangeNotifier::RemoveConnectionTypeObserver( ConnectionTypeObserver* observer) { - if (g_network_change_notifier) { - g_network_change_notifier->connection_type_observer_list_->RemoveObserver( - observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } void NetworkChangeNotifier::RemoveDNSObserver(DNSObserver* observer) { - if (g_network_change_notifier) { - g_network_change_notifier->resolver_state_observer_list_->RemoveObserver( - observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } void NetworkChangeNotifier::RemoveNetworkChangeObserver( NetworkChangeObserver* observer) { - if (g_network_change_notifier) { - g_network_change_notifier->network_change_observer_list_->RemoveObserver( - observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } void NetworkChangeNotifier::RemoveMaxBandwidthObserver( MaxBandwidthObserver* observer) { - if (g_network_change_notifier) { - g_network_change_notifier->max_bandwidth_observer_list_->RemoveObserver( - observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } void NetworkChangeNotifier::RemoveNetworkObserver(NetworkObserver* observer) { - DCHECK(AreNetworkHandlesSupported()); - if (g_network_change_notifier) { - g_network_change_notifier->network_observer_list_->RemoveObserver(observer); + if (observer->observer_list_) { + observer->observer_list_->RemoveObserver(observer); + observer->observer_list_.reset(); } } @@ -760,7 +802,9 @@ void NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChange( void NetworkChangeNotifier::SetDnsConfig(const DnsConfig& config) { if (!g_network_change_notifier) return; - if (g_network_change_notifier->network_state_->SetDnsConfig(config)) { + scoped_refptr<NetworkState> network_state = + g_network_change_notifier->network_state_; + if (network_state->SetDnsConfig(config)) { NotifyObserversOfDNSChange(); } else { NotifyObserversOfInitialDNSConfigRead(); @@ -770,7 +814,9 @@ void NetworkChangeNotifier::SetDnsConfig(const DnsConfig& config) { void NetworkChangeNotifier::ClearDnsConfigForTesting() { if (!g_network_change_notifier) return; - g_network_change_notifier->network_state_->ClearDnsConfigForTesting(); + scoped_refptr<NetworkState> network_state = + g_network_change_notifier->network_state_; + network_state->ClearDnsConfigForTesting(); } void NetworkChangeNotifier::NotifyObserversOfIPAddressChangeImpl() { diff --git a/chromium/net/base/network_change_notifier.h b/chromium/net/base/network_change_notifier.h index 28ab6687593..9cf4f6f240b 100644 --- a/chromium/net/base/network_change_notifier.h +++ b/chromium/net/base/network_change_notifier.h @@ -11,6 +11,7 @@ #include <vector> #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/observer_list_threadsafe.h" #include "base/time/time.h" #include "net/base/net_export.h" @@ -109,10 +110,14 @@ class NET_EXPORT NetworkChangeNotifier { virtual void OnIPAddressChanged() = 0; protected: - IPAddressObserver() {} - virtual ~IPAddressObserver() {} + IPAddressObserver(); + virtual ~IPAddressObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<IPAddressObserver>> + observer_list_; + DISALLOW_COPY_AND_ASSIGN(IPAddressObserver); }; @@ -126,10 +131,14 @@ class NET_EXPORT NetworkChangeNotifier { virtual void OnConnectionTypeChanged(ConnectionType type) = 0; protected: - ConnectionTypeObserver() {} - virtual ~ConnectionTypeObserver() {} + ConnectionTypeObserver(); + virtual ~ConnectionTypeObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<ConnectionTypeObserver>> + observer_list_; + DISALLOW_COPY_AND_ASSIGN(ConnectionTypeObserver); }; @@ -148,10 +157,13 @@ class NET_EXPORT NetworkChangeNotifier { virtual void OnInitialDNSConfigRead(); protected: - DNSObserver() {} - virtual ~DNSObserver() {} + DNSObserver(); + virtual ~DNSObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<DNSObserver>> observer_list_; + DISALLOW_COPY_AND_ASSIGN(DNSObserver); }; @@ -185,10 +197,14 @@ class NET_EXPORT NetworkChangeNotifier { virtual void OnNetworkChanged(ConnectionType type) = 0; protected: - NetworkChangeObserver() {} - virtual ~NetworkChangeObserver() {} + NetworkChangeObserver(); + virtual ~NetworkChangeObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<NetworkChangeObserver>> + observer_list_; + DISALLOW_COPY_AND_ASSIGN(NetworkChangeObserver); }; @@ -203,10 +219,14 @@ class NET_EXPORT NetworkChangeNotifier { ConnectionType type) = 0; protected: - MaxBandwidthObserver() {} - virtual ~MaxBandwidthObserver() {} + MaxBandwidthObserver(); + virtual ~MaxBandwidthObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<MaxBandwidthObserver>> + observer_list_; + DISALLOW_COPY_AND_ASSIGN(MaxBandwidthObserver); }; @@ -245,10 +265,13 @@ class NET_EXPORT NetworkChangeNotifier { virtual void OnNetworkMadeDefault(NetworkHandle network) = 0; protected: - NetworkObserver() {} - virtual ~NetworkObserver() {} + NetworkObserver(); + virtual ~NetworkObserver(); private: + friend NetworkChangeNotifier; + scoped_refptr<base::ObserverListThreadSafe<NetworkObserver>> observer_list_; + DISALLOW_COPY_AND_ASSIGN(NetworkObserver); }; @@ -536,6 +559,10 @@ class NET_EXPORT NetworkChangeNotifier { // have the same type, return it, otherwise return CONNECTION_UNKNOWN. static ConnectionType ConnectionTypeFromInterfaces(); + // Clears the global NetworkChangeNotifier pointer. This should be called + // as early as possible in the destructor to prevent races. + void ClearGlobalPointer(); + private: friend class HostResolverManagerDnsTest; friend class NetworkChangeNotifierAndroidTest; @@ -569,7 +596,7 @@ class NET_EXPORT NetworkChangeNotifier { network_observer_list_; // The current network state. Hosts DnsConfig, exposed via GetDnsConfig. - std::unique_ptr<NetworkState> network_state_; + scoped_refptr<NetworkState> network_state_; // Computes NetworkChange signal from IPAddress and ConnectionType signals. std::unique_ptr<NetworkChangeCalculator> network_change_calculator_; @@ -577,6 +604,9 @@ class NET_EXPORT NetworkChangeNotifier { // Set true to disable non-test notifications (to prevent flakes in tests). static bool test_notifications_only_; + // Indicates if this instance cleared g_network_change_notifier_ yet. + bool cleared_global_pointer_ = false; + DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifier); }; diff --git a/chromium/net/base/network_change_notifier_fuchsia.cc b/chromium/net/base/network_change_notifier_fuchsia.cc index 0b66a09e2a2..f3d48538629 100644 --- a/chromium/net/base/network_change_notifier_fuchsia.cc +++ b/chromium/net/base/network_change_notifier_fuchsia.cc @@ -29,9 +29,25 @@ NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia( NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia( fuchsia::netstack::NetstackPtr netstack, uint32_t required_features) - : required_features_(required_features), netstack_(std::move(netstack)) { - DCHECK(netstack_); - + : required_features_(required_features) { + DCHECK(netstack); + + // Temporarily re-wrap our Netstack channel so we can query the interfaces + // and routing table synchronously to populate the initial state. + fuchsia::netstack::NetstackSyncPtr sync_netstack; + sync_netstack.Bind(netstack.Unbind()); + + // Manually fetch the interfaces and routes. + std::vector<fuchsia::netstack::NetInterface> interfaces; + zx_status_t status = sync_netstack->GetInterfaces(&interfaces); + ZX_CHECK(status == ZX_OK, status) << "synchronous GetInterfaces()"; + std::vector<fuchsia::netstack::RouteTableEntry> routes; + status = sync_netstack->GetRouteTable(&routes); + ZX_CHECK(status == ZX_OK, status) << "synchronous GetInterfaces()"; + OnRouteTableReceived(std::move(interfaces), std::move(routes), false); + + // Re-wrap Netstack back into an asynchronous pointer. + netstack_.Bind(sync_netstack.Unbind()); netstack_.set_error_handler([](zx_status_t status) { // TODO(https://crbug.com/901092): Unit tests that use NetworkService are // crashing because NetworkService does not clean up properly, and the @@ -41,15 +57,11 @@ NetworkChangeNotifierFuchsia::NetworkChangeNotifierFuchsia( }); netstack_.events().OnInterfacesChanged = fit::bind_member( this, &NetworkChangeNotifierFuchsia::ProcessInterfaceList); - - // Manually fetch the interface list, on which to base an initial - // ConnectionType. - netstack_->GetInterfaces(fit::bind_member( - this, &NetworkChangeNotifierFuchsia::ProcessInterfaceList)); } NetworkChangeNotifierFuchsia::~NetworkChangeNotifierFuchsia() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + ClearGlobalPointer(); } NetworkChangeNotifier::ConnectionType @@ -64,13 +76,15 @@ void NetworkChangeNotifierFuchsia::ProcessInterfaceList( netstack_->GetRouteTable( [this, interfaces = std::move(interfaces)]( std::vector<fuchsia::netstack::RouteTableEntry> route_table) mutable { - OnRouteTableReceived(std::move(interfaces), std::move(route_table)); + OnRouteTableReceived(std::move(interfaces), std::move(route_table), + true); }); } void NetworkChangeNotifierFuchsia::OnRouteTableReceived( std::vector<fuchsia::netstack::NetInterface> interfaces, - std::vector<fuchsia::netstack::RouteTableEntry> route_table) { + std::vector<fuchsia::netstack::RouteTableEntry> route_table, + bool notify_observers) { // Create a set of NICs that have default routes (ie 0.0.0.0). base::flat_set<uint32_t> default_route_ids; for (const auto& route : route_table) { @@ -119,20 +133,16 @@ void NetworkChangeNotifierFuchsia::OnRouteTableReceived( } } - bool connection_type_changed = false; - if (connection_type != cached_connection_type_) { - base::subtle::Release_Store(&cached_connection_type_, connection_type); - connection_type_changed = true; - } - if (addresses != cached_addresses_) { std::swap(cached_addresses_, addresses); - NotifyObserversOfIPAddressChange(); - connection_type_changed = true; + if (notify_observers) + NotifyObserversOfIPAddressChange(); } - if (connection_type_changed) { - NotifyObserversOfConnectionTypeChange(); + if (connection_type != cached_connection_type_) { + base::subtle::Release_Store(&cached_connection_type_, connection_type); + if (notify_observers) + NotifyObserversOfConnectionTypeChange(); } } diff --git a/chromium/net/base/network_change_notifier_fuchsia.h b/chromium/net/base/network_change_notifier_fuchsia.h index e1b73a06707..acee7d48f14 100644 --- a/chromium/net/base/network_change_notifier_fuchsia.h +++ b/chromium/net/base/network_change_notifier_fuchsia.h @@ -27,15 +27,11 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierFuchsia explicit NetworkChangeNotifierFuchsia(uint32_t required_features); ~NetworkChangeNotifierFuchsia() override; + // NetworkChangeNotifier implementation. + ConnectionType GetCurrentConnectionType() const override; + private: friend class NetworkChangeNotifierFuchsiaTest; - FRIEND_TEST_ALL_PREFIXES(NetworkChangeNotifierFuchsiaTest, - FindsInterfaceWithRequiredFeature); - FRIEND_TEST_ALL_PREFIXES(NetworkChangeNotifierFuchsiaTest, FoundWiFi); - FRIEND_TEST_ALL_PREFIXES(NetworkChangeNotifierFuchsiaTest, - FoundWiFiNonDefault); - FRIEND_TEST_ALL_PREFIXES(NetworkChangeNotifierFuchsiaTest, - IgnoresInterfaceWithMissingFeature); // For testing purposes. Receives a |netstack| pointer for easy mocking. // Interfaces can be filtered out by passing in |required_features|, which is @@ -53,10 +49,8 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierFuchsia // connection type changes are detected. void OnRouteTableReceived( std::vector<fuchsia::netstack::NetInterface> interfaces, - std::vector<fuchsia::netstack::RouteTableEntry> table); - - // NetworkChangeNotifier implementation. - ConnectionType GetCurrentConnectionType() const override; + std::vector<fuchsia::netstack::RouteTableEntry> table, + bool notify_observers); // Bitmap of required features for an interface to be taken into account. The // features are defined in fuchsia::hardware::ethernet. diff --git a/chromium/net/base/network_change_notifier_fuchsia_unittest.cc b/chromium/net/base/network_change_notifier_fuchsia_unittest.cc index a68969b2dd9..b301f08d878 100644 --- a/chromium/net/base/network_change_notifier_fuchsia_unittest.cc +++ b/chromium/net/base/network_change_notifier_fuchsia_unittest.cc @@ -10,8 +10,11 @@ #include <utility> #include <vector> +#include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/threading/sequence_bound.h" +#include "base/threading/thread.h" #include "net/base/ip_address.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -93,8 +96,6 @@ fuchsia::netstack::NetInterface CreateNetInterface( } // Partial fake implementation of a Netstack. -// GMock is not used because the methods make heavy use of move-only datatypes, -// which aren't handled well by GMock. class FakeNetstack : public fuchsia::netstack::testing::Netstack_TestBase { public: explicit FakeNetstack( @@ -115,18 +116,27 @@ class FakeNetstack : public fuchsia::netstack::testing::Netstack_TestBase { // Sends the accumulated |interfaces_| to the OnInterfacesChanged event. void NotifyInterfaces() { + did_work_ = true; binding_.events().OnInterfacesChanged(std::move(interfaces_)); interfaces_.clear(); } - fidl::Binding<fuchsia::netstack::Netstack>& binding() { return binding_; } + // Sets |*did_work_out| to |true| if any FIDL API was called since the + // last DidDoWork() call. This is used by the FakeNetstackAsync::Synchronize() + // call to determine when to stop pumping the message loops. + void DidDoWork(base::OnceClosure done, bool* did_work_out) { + *did_work_out = std::exchange(did_work_, false); + std::move(done).Run(); + } private: void GetInterfaces(GetInterfacesCallback callback) override { + did_work_ = true; callback(std::move(interfaces_)); } void GetRouteTable(GetRouteTableCallback callback) override { + did_work_ = true; std::vector<fuchsia::netstack::RouteTableEntry> table(2); table[0] = CreateRouteTableEntry(kDefaultNic, true); table[1] = CreateRouteTableEntry(kSecondaryNic, false); @@ -142,13 +152,70 @@ class FakeNetstack : public fuchsia::netstack::testing::Netstack_TestBase { fidl::Binding<fuchsia::netstack::Netstack> binding_; + // |true| if any FIDL API was called since the last DidDoWork(). + bool did_work_ = false; + DISALLOW_COPY_AND_ASSIGN(FakeNetstack); }; -class MockNetworkChangeObserver - : public NetworkChangeNotifier::NetworkChangeObserver { +class FakeNetstackAsync { public: - MOCK_METHOD1(OnNetworkChanged, void(NetworkChangeNotifier::ConnectionType)); + explicit FakeNetstackAsync( + fidl::InterfaceRequest<fuchsia::netstack::Netstack> netstack_request) + : thread_("Netstack Thread") { + base::Thread::Options options(base::MessageLoop::TYPE_IO, 0); + CHECK(thread_.StartWithOptions(options)); + netstack_ = base::SequenceBound<FakeNetstack>(thread_.task_runner(), + std::move(netstack_request)); + } + ~FakeNetstackAsync() = default; + + // Asynchronously update the state of the netstack. + void PushInterface(fuchsia::netstack::NetInterface&& interface) { + netstack_.Post(FROM_HERE, &FakeNetstack::PushInterface, + std::move(interface)); + } + void PushRouteTableEntry(fuchsia::netstack::RouteTableEntry&& route) { + netstack_.Post(FROM_HERE, &FakeNetstack::PushRouteTableEntry, + std::move(route)); + } + void NotifyInterfaces() { + netstack_.Post(FROM_HERE, &FakeNetstack::NotifyInterfaces); + } + + // Pump the test main and Netstack loops until things stabilize. + void Synchronize() { + // Ensure that pending Push*() and Notify*() calls were processed. + thread_.FlushForTesting(); + + // Spin the Netstack until it stops receiving FIDL calls. + bool did_work = false; + do { + base::RunLoop loop; + did_work = false; + netstack_.Post(FROM_HERE, &FakeNetstack::DidDoWork, + loop.QuitWhenIdleClosure(), &did_work); + loop.Run(); + } while (did_work); + } + + private: + base::Thread thread_; + base::SequenceBound<FakeNetstack> netstack_; + + DISALLOW_COPY_AND_ASSIGN(FakeNetstackAsync); +}; + +class MockConnectionTypeObserver + : public NetworkChangeNotifier::ConnectionTypeObserver { + public: + MOCK_METHOD1(OnConnectionTypeChanged, + void(NetworkChangeNotifier::ConnectionType)); +}; + +class MockIPAddressObserver : public NetworkChangeNotifier::IPAddressObserver { + public: + MOCK_METHOD0(OnIPAddressChanged, void()); }; } // namespace @@ -156,37 +223,40 @@ class MockNetworkChangeObserver class NetworkChangeNotifierFuchsiaTest : public testing::Test { public: NetworkChangeNotifierFuchsiaTest() : netstack_(netstack_ptr_.NewRequest()) {} - - ~NetworkChangeNotifierFuchsiaTest() override {} + ~NetworkChangeNotifierFuchsiaTest() override = default; // Creates a NetworkChangeNotifier and spins the MessageLoop to allow it to // populate from the list of interfaces which have already been added to // |netstack_|. |observer_| is registered last, so that tests need only // express expectations on changes they make themselves. void CreateNotifier(uint32_t required_features = 0) { + // Ensure that the Netstack internal state is up-to-date before the + // notifier queries it. + netstack_.Synchronize(); + notifier_.reset(new NetworkChangeNotifierFuchsia(std::move(netstack_ptr_), required_features)); - // RunUntilIdle() is sufficient to populate the notifier from |netstack_|, - // since our fake netstack runs on the same MessageLoop. - ASSERT_EQ(notifier_->GetConnectionType(), - NetworkChangeNotifier::CONNECTION_UNKNOWN); - base::RunLoop().RunUntilIdle(); - - NetworkChangeNotifier::AddNetworkChangeObserver(&observer_); + NetworkChangeNotifier::AddConnectionTypeObserver(&observer_); + NetworkChangeNotifier::AddIPAddressObserver(&ip_observer_); } void TearDown() override { + // Spin the loops to catch any unintended notifications. + netstack_.Synchronize(); + if (notifier_) { - NetworkChangeNotifier::RemoveNetworkChangeObserver(&observer_); + NetworkChangeNotifier::RemoveConnectionTypeObserver(&observer_); + NetworkChangeNotifier::RemoveIPAddressObserver(&ip_observer_); } } protected: base::MessageLoopForIO message_loop_; - testing::StrictMock<MockNetworkChangeObserver> observer_; + testing::StrictMock<MockConnectionTypeObserver> observer_; + testing::StrictMock<MockIPAddressObserver> ip_observer_; fuchsia::netstack::NetstackPtr netstack_ptr_; - FakeNetstack netstack_; + FakeNetstackAsync netstack_; // Allows us to allocate our own NetworkChangeNotifier for unit testing. NetworkChangeNotifier::DisableForTest disable_for_test_; @@ -198,6 +268,12 @@ class NetworkChangeNotifierFuchsiaTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierFuchsiaTest); }; +TEST_F(NetworkChangeNotifierFuchsiaTest, InitialState) { + CreateNotifier(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_NONE, + notifier_->GetCurrentConnectionType()); +} + TEST_F(NetworkChangeNotifierFuchsiaTest, NoChange) { netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, @@ -206,7 +282,8 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, NoChange) { netstack_.PushRouteTableEntry(CreateRouteTableEntry(kDefaultNic, true)); CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, @@ -214,7 +291,6 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, NoChange) { CreateIPv4Address(255, 255, 255, 0), {})); netstack_.PushRouteTableEntry(CreateRouteTableEntry(kDefaultNic, true)); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, NoChangeV6) { @@ -223,14 +299,12 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, NoChangeV6) { CreateIPv6Address({0xfe, 0x80, 0x01}), CreateIPv6Address({0xfe, 0x80}), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv6Address({0xfe, 0x80, 0x01}), CreateIPv6Address({0xfe, 0x80}), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, MultiInterfaceNoChange) { @@ -243,7 +317,6 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, MultiInterfaceNoChange) { 0, CreateIPv4Address(169, 254, 0, 2), CreateIPv4Address(255, 255, 255, 0), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, @@ -254,7 +327,6 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, MultiInterfaceNoChange) { 0, CreateIPv4Address(169, 254, 0, 3), CreateIPv4Address(255, 255, 255, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, MultiV6IPNoChange) { @@ -264,8 +336,8 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, MultiV6IPNoChange) { kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), std::move(addresses))); + CreateNotifier(); - base::RunLoop().RunUntilIdle(); addresses.push_back(CreateSubnet({0xfe, 0x80, 0x01}, 2)); netstack_.PushInterface(CreateNetInterface( @@ -273,83 +345,78 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, MultiV6IPNoChange) { CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), std::move(addresses))); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, IpChange) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_UNKNOWN)); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); + netstack_.PushInterface(CreateNetInterface( kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(10, 0, 0, 1), CreateIPv4Address(255, 255, 0, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, IpChangeV6) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv6Address({0xfe, 0x80, 0x01}), CreateIPv6Address({0xfe, 0x80}), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_UNKNOWN)); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv6Address({0xfe, 0x80, 0x02}), CreateIPv6Address({0xfe, 0x80}), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, MultiV6IPChanged) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + std::vector<fuchsia::net::Subnet> addresses; addresses.push_back(CreateSubnet({0xfe, 0x80, 0x01}, 2)); netstack_.PushInterface(CreateNetInterface( kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), std::move(addresses))); + CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_UNKNOWN)); addresses.push_back(CreateSubnet({0xfe, 0x80, 0x02}, 2)); netstack_.PushInterface(CreateNetInterface( kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(10, 0, 0, 1), CreateIPv4Address(255, 255, 0, 0), std::move(addresses))); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, Ipv6AdditionalIpChange) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); + CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_UNKNOWN)); std::vector<fuchsia::net::Subnet> addresses; addresses.push_back(CreateSubnet({0xfe, 0x80, 0x01}, 2)); netstack_.PushInterface(CreateNetInterface( @@ -357,75 +424,82 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, Ipv6AdditionalIpChange) { CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), std::move(addresses))); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, InterfaceDown) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + EXPECT_CALL(observer_, + OnConnectionTypeChanged(NetworkChangeNotifier::CONNECTION_NONE)); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); + CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); netstack_.PushInterface( CreateNetInterface(1, 0, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 0, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, InterfaceUp) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + EXPECT_CALL(observer_, OnConnectionTypeChanged( + NetworkChangeNotifier::CONNECTION_UNKNOWN)); + netstack_.PushInterface( CreateNetInterface(1, 0, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); + CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_NONE, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_UNKNOWN)); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 0, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, InterfaceDeleted) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + EXPECT_CALL(observer_, + OnConnectionTypeChanged(NetworkChangeNotifier::CONNECTION_NONE)); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, + notifier_->GetCurrentConnectionType()); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); + // NotifyInterfaces() with no new PushInterfaces() means removing everything. netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, InterfaceAdded) { + EXPECT_CALL(ip_observer_, OnIPAddressChanged()); + EXPECT_CALL(observer_, + OnConnectionTypeChanged(NetworkChangeNotifier::CONNECTION_WIFI)); + // Initial interface list is intentionally left empty. CreateNotifier(); - base::RunLoop().RunUntilIdle(); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_NONE)); - EXPECT_CALL(observer_, - OnNetworkChanged(NetworkChangeNotifier::CONNECTION_WIFI)); + EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_NONE, + notifier_->GetCurrentConnectionType()); + netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, fuchsia::hardware::ethernet::INFO_FEATURE_WLAN, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, SecondaryInterfaceAddedNoop) { @@ -434,7 +508,6 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, SecondaryInterfaceAddedNoop) { CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); netstack_.PushInterface( CreateNetInterface(kSecondaryNic, fuchsia::netstack::NetInterfaceFlagUp, @@ -445,7 +518,6 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, SecondaryInterfaceAddedNoop) { CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, SecondaryInterfaceDeletedNoop) { @@ -458,14 +530,12 @@ TEST_F(NetworkChangeNotifierFuchsiaTest, SecondaryInterfaceDeletedNoop) { 0, CreateIPv4Address(169, 254, 0, 2), CreateIPv4Address(255, 255, 255, 0), {})); CreateNotifier(); - base::RunLoop().RunUntilIdle(); netstack_.PushInterface( CreateNetInterface(kDefaultNic, fuchsia::netstack::NetInterfaceFlagUp, 0, CreateIPv4Address(169, 254, 0, 1), CreateIPv4Address(255, 255, 255, 0), {})); netstack_.NotifyInterfaces(); - base::RunLoop().RunUntilIdle(); } TEST_F(NetworkChangeNotifierFuchsiaTest, FoundWiFi) { diff --git a/chromium/net/base/network_change_notifier_linux.cc b/chromium/net/base/network_change_notifier_linux.cc index ff0b2773bbf..682395d63da 100644 --- a/chromium/net/base/network_change_notifier_linux.cc +++ b/chromium/net/base/network_change_notifier_linux.cc @@ -107,7 +107,9 @@ NetworkChangeNotifierLinux::NetworkChangeNotifierLinux( base::Unretained(blocking_thread_objects_.get()))); } -NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() = default; +NetworkChangeNotifierLinux::~NetworkChangeNotifierLinux() { + ClearGlobalPointer(); +} // static NetworkChangeNotifier::NetworkChangeCalculatorParams diff --git a/chromium/net/base/network_change_notifier_mac.cc b/chromium/net/base/network_change_notifier_mac.cc index 7f11018922f..76ad20fd8c1 100644 --- a/chromium/net/base/network_change_notifier_mac.cc +++ b/chromium/net/base/network_change_notifier_mac.cc @@ -56,6 +56,7 @@ NetworkChangeNotifierMac::NetworkChangeNotifierMac() } NetworkChangeNotifierMac::~NetworkChangeNotifierMac() { + ClearGlobalPointer(); // Delete the ConfigWatcher to join the notifier thread, ensuring that // StartReachabilityNotifications() has an opportunity to run to completion. config_watcher_.reset(); diff --git a/chromium/net/base/network_change_notifier_posix.cc b/chromium/net/base/network_change_notifier_posix.cc index 58610f6add7..adb09dc4cd5 100644 --- a/chromium/net/base/network_change_notifier_posix.cc +++ b/chromium/net/base/network_change_notifier_posix.cc @@ -66,7 +66,9 @@ NetworkChangeNotifierPosix::NetworkChangeNotifierPosix( OnDNSChanged(); } -NetworkChangeNotifierPosix::~NetworkChangeNotifierPosix() = default; +NetworkChangeNotifierPosix::~NetworkChangeNotifierPosix() { + ClearGlobalPointer(); +} void NetworkChangeNotifierPosix::OnDNSChanged() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); diff --git a/chromium/net/base/network_change_notifier_win.cc b/chromium/net/base/network_change_notifier_win.cc index 3393d9a03b3..44336d60c12 100644 --- a/chromium/net/base/network_change_notifier_win.cc +++ b/chromium/net/base/network_change_notifier_win.cc @@ -12,7 +12,10 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" +#include "base/task/post_task.h" +#include "base/task/task_traits.h" #include "base/task_runner_util.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" @@ -30,32 +33,18 @@ const int kWatchForAddressChangeRetryIntervalMs = 500; } // namespace -// Thread on which we can run DnsConfigService, which requires AssertIOAllowed -// to open registry keys and to handle FilePathWatcher updates. -class NetworkChangeNotifierWin::DnsConfigServiceThread : public base::Thread { - public: - DnsConfigServiceThread() : base::Thread("DnsConfigService") {} - - ~DnsConfigServiceThread() override { Stop(); } - - void Init() override { - service_ = DnsConfigService::CreateSystemService(); - service_->WatchConfig(base::Bind(&NetworkChangeNotifier::SetDnsConfig)); - } - - void CleanUp() override { service_.reset(); } - - private: - std::unique_ptr<DnsConfigService> service_; - - DISALLOW_COPY_AND_ASSIGN(DnsConfigServiceThread); -}; - NetworkChangeNotifierWin::NetworkChangeNotifierWin() : NetworkChangeNotifier(NetworkChangeCalculatorParamsWin()), is_watching_(false), sequential_failures_(0), - dns_config_service_thread_(new DnsConfigServiceThread()), + dns_config_service_runner_( + base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()})), + dns_config_service_( + DnsConfigService::CreateSystemService().release(), + // Ensure DnsConfigService lives on |dns_config_service_runner_| + // to prevent races where NetworkChangeNotifierWin outlives + // ScopedTaskEnvironment. https://crbug.com/938126 + base::OnTaskRunnerDeleter(dns_config_service_runner_)), last_computed_connection_type_(RecomputeCurrentConnectionType()), last_announced_offline_(last_computed_connection_type_ == CONNECTION_NONE), @@ -65,7 +54,8 @@ NetworkChangeNotifierWin::NetworkChangeNotifierWin() } NetworkChangeNotifierWin::~NetworkChangeNotifierWin() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + ClearGlobalPointer(); if (is_watching_) { CancelIPChangeNotify(&addr_overlapped_); addr_watcher_.StopWatching(); @@ -204,15 +194,15 @@ NetworkChangeNotifierWin::RecomputeCurrentConnectionType() const { : NetworkChangeNotifier::CONNECTION_NONE; } -void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const { +void NetworkChangeNotifierWin::RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const { // Unretained is safe in this call because this object owns the thread and the // thread is stopped in this object's destructor. base::PostTaskAndReplyWithResult( - dns_config_service_thread_->task_runner().get(), FROM_HERE, - base::Bind(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, - base::Unretained(this)), - reply_callback); + dns_config_service_runner_.get(), FROM_HERE, + base::BindOnce(&NetworkChangeNotifierWin::RecomputeCurrentConnectionType, + base::Unretained(this)), + std::move(reply_callback)); } NetworkChangeNotifier::ConnectionType @@ -228,19 +218,19 @@ void NetworkChangeNotifierWin::SetCurrentConnectionType( } void NetworkChangeNotifierWin::OnObjectSignaled(HANDLE object) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(is_watching_); is_watching_ = false; // Start watching for the next address change. WatchForAddressChange(); - RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + RecomputeCurrentConnectionTypeOnDnsSequence(base::BindOnce( &NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); SetCurrentConnectionType(connection_type); NotifyObserversOfIPAddressChange(); @@ -257,7 +247,7 @@ void NetworkChangeNotifierWin::NotifyObservers(ConnectionType connection_type) { } void NetworkChangeNotifierWin::WatchForAddressChange() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!is_watching_); // NotifyAddrChange occasionally fails with ERROR_OPEN_FAILED for unknown @@ -287,7 +277,7 @@ void NetworkChangeNotifierWin::WatchForAddressChange() { // network change event, since network changes were not being observed in // that interval. if (sequential_failures_ > 0) { - RecomputeCurrentConnectionTypeOnDnsThread( + RecomputeCurrentConnectionTypeOnDnsSequence( base::Bind(&NetworkChangeNotifierWin::NotifyObservers, weak_factory_.GetWeakPtr())); } @@ -302,11 +292,15 @@ void NetworkChangeNotifierWin::WatchForAddressChange() { } bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - if (!dns_config_service_thread_->IsRunning()) { - dns_config_service_thread_->StartWithOptions( - base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!posted_watch_config_) { + posted_watch_config_ = true; + dns_config_service_runner_->PostTask( + FROM_HERE, base::BindOnce(&DnsConfigService::WatchConfig, + base::Unretained(dns_config_service_.get()), + base::BindRepeating( + &NetworkChangeNotifier::SetDnsConfig))); } ResetEventIfSignaled(addr_overlapped_.hEvent); @@ -320,7 +314,7 @@ bool NetworkChangeNotifierWin::WatchForAddressChangeInternal() { } void NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChange() { - RecomputeCurrentConnectionTypeOnDnsThread(base::Bind( + RecomputeCurrentConnectionTypeOnDnsSequence(base::BindOnce( &NetworkChangeNotifierWin::NotifyParentOfConnectionTypeChangeImpl, weak_factory_.GetWeakPtr())); } diff --git a/chromium/net/base/network_change_notifier_win.h b/chromium/net/base/network_change_notifier_win.h index beef6bad9f7..e7a00b9cd71 100644 --- a/chromium/net/base/network_change_notifier_win.h +++ b/chromium/net/base/network_change_notifier_win.h @@ -12,17 +12,25 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" -#include "base/threading/thread_checker.h" +#include "base/sequence_checker.h" #include "base/timer/timer.h" #include "base/win/object_watcher.h" #include "net/base/net_export.h" #include "net/base/network_change_notifier.h" +namespace base { +class SequencedTaskRunner; +struct OnTaskRunnerDeleter; +} // namespace base + namespace net { -// NetworkChangeNotifierWin uses a ThreadChecker, as all its internal -// notification code must be called on the thread it is created and destroyed +class DnsConfigService; + +// NetworkChangeNotifierWin uses a SequenceChecker, as all its internal +// notification code must be called on the sequence it is created and destroyed // on. All the NetworkChangeNotifier methods it implements are threadsafe. class NET_EXPORT_PRIVATE NetworkChangeNotifierWin : public NetworkChangeNotifier, @@ -32,8 +40,8 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin // Begins listening for a single subsequent address change. If it fails to // start watching, it retries on a timer. Must be called only once, on the - // thread |this| was created on. This cannot be called in the constructor, as - // WatchForAddressChangeInternal is mocked out in unit tests. + // sequence |this| was created on. This cannot be called in the constructor, + // as WatchForAddressChangeInternal is mocked out in unit tests. // TODO(mmenke): Consider making this function a part of the // NetworkChangeNotifier interface, so other subclasses can be // unit tested in similar fashion, as needed. @@ -48,30 +56,29 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin int sequential_failures() { return sequential_failures_; } private: - class DnsConfigServiceThread; friend class NetworkChangeNotifierWinTest; // NetworkChangeNotifier methods: ConnectionType GetCurrentConnectionType() const override; // ObjectWatcher::Delegate methods: - // Must only be called on the thread |this| was created on. + // Must only be called on the sequence |this| was created on. void OnObjectSignaled(HANDLE object) override; // Does the actual work to determine the current connection type. // It is not thread safe, see crbug.com/324913. virtual ConnectionType RecomputeCurrentConnectionType() const; - // Calls RecomputeCurrentConnectionTypeImpl on the DNS thread and runs - // |reply_callback| with the type on the calling thread. - virtual void RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const; + // Calls RecomputeCurrentConnectionTypeImpl on the DNS sequence and runs + // |reply_callback| with the type on the calling sequence. + virtual void RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const; void SetCurrentConnectionType(ConnectionType connection_type); // Notifies IP address change observers of a change immediately, and notifies // network state change observers on a delay. Must only be called on the - // thread |this| was created on. + // sequence |this| was created on. void NotifyObservers(ConnectionType connection_type); // Forwards connection type notifications to parent class. @@ -80,14 +87,14 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin // Tries to start listening for a single subsequent address change. Returns // false on failure. The caller is responsible for updating |is_watching_|. - // Virtual for unit tests. Must only be called on the thread |this| was + // Virtual for unit tests. Must only be called on the sequence |this| was // created on. virtual bool WatchForAddressChangeInternal(); static NetworkChangeCalculatorParams NetworkChangeCalculatorParamsWin(); - // All member variables may only be accessed on the thread |this| was created - // on. + // All member variables may only be accessed on the sequence |this| was + // created on. // False when not currently watching for network change events. This only // happens on initialization and when WatchForAddressChangeInternal fails and @@ -102,8 +109,11 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin // Number of times WatchForAddressChange has failed in a row. int sequential_failures_; - // Thread on which we can run DnsConfigService. - std::unique_ptr<DnsConfigServiceThread> dns_config_service_thread_; + // |dns_config_service_| will live on this runner. + scoped_refptr<base::SequencedTaskRunner> dns_config_service_runner_; + // DnsConfigService that lives on |dns_config_service_runner_|. + std::unique_ptr<DnsConfigService, base::OnTaskRunnerDeleter> + dns_config_service_; mutable base::Lock last_computed_connection_type_lock_; ConnectionType last_computed_connection_type_; @@ -114,7 +124,10 @@ class NET_EXPORT_PRIVATE NetworkChangeNotifierWin // Number of times polled to check if still offline. int offline_polls_; - THREAD_CHECKER(thread_checker_); + // Keeps track of whether DnsConfigService::WatchConfig() has been called. + bool posted_watch_config_ = false; + + SEQUENCE_CHECKER(sequence_checker_); // Used for calling WatchForAddressChange again on failure. base::WeakPtrFactory<NetworkChangeNotifierWin> weak_factory_; diff --git a/chromium/net/base/network_change_notifier_win_unittest.cc b/chromium/net/base/network_change_notifier_win_unittest.cc index ba695806080..0d512053c2d 100644 --- a/chromium/net/base/network_change_notifier_win_unittest.cc +++ b/chromium/net/base/network_change_notifier_win_unittest.cc @@ -43,10 +43,10 @@ class TestNetworkChangeNotifierWin : public NetworkChangeNotifierWin { } // From NetworkChangeNotifierWin. - void RecomputeCurrentConnectionTypeOnDnsThread( - base::Callback<void(ConnectionType)> reply_callback) const override { + void RecomputeCurrentConnectionTypeOnDnsSequence( + base::OnceCallback<void(ConnectionType)> reply_callback) const override { base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(reply_callback, + FROM_HERE, base::BindOnce(std::move(reply_callback), NetworkChangeNotifier::CONNECTION_UNKNOWN)); } diff --git a/chromium/net/base/network_interfaces_unittest.cc b/chromium/net/base/network_interfaces_unittest.cc index 843de293131..b5c5a193631 100644 --- a/chromium/net/base/network_interfaces_unittest.cc +++ b/chromium/net/base/network_interfaces_unittest.cc @@ -18,6 +18,8 @@ #elif defined(OS_WIN) #include <iphlpapi.h> #include <objbase.h> +#include "base/strings/string_util.h" +#include "base/win/win_util.h" #endif namespace net { @@ -48,10 +50,8 @@ TEST(NetworkInterfacesTest, GetNetworkList) { GUID guid; EXPECT_EQ(static_cast<DWORD>(NO_ERROR), ConvertInterfaceLuidToGuid(&luid, &guid)); - LPOLESTR name; - StringFromCLSID(guid, &name); - EXPECT_STREQ(base::UTF8ToWide(it->name).c_str(), name); - CoTaskMemFree(name); + auto name = base::win::String16FromGUID(guid); + EXPECT_EQ(base::as_u16cstr(base::UTF8ToWide(it->name)), name); if (it->type == NetworkChangeNotifier::CONNECTION_WIFI) { EXPECT_NE(WIFI_PHY_LAYER_PROTOCOL_NONE, GetWifiPHYLayerProtocol()); diff --git a/chromium/net/base/network_isolation_key.cc b/chromium/net/base/network_isolation_key.cc new file mode 100644 index 00000000000..183c87f5260 --- /dev/null +++ b/chromium/net/base/network_isolation_key.cc @@ -0,0 +1,48 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/network_isolation_key.h" + +namespace net { + +NetworkIsolationKey::NetworkIsolationKey( + const base::Optional<url::Origin>& top_frame_origin) + : top_frame_origin_(top_frame_origin) {} + +NetworkIsolationKey::NetworkIsolationKey() = default; + +NetworkIsolationKey::NetworkIsolationKey( + const NetworkIsolationKey& network_isolation_key) = default; + +NetworkIsolationKey::~NetworkIsolationKey() = default; + +NetworkIsolationKey& NetworkIsolationKey::operator=( + const NetworkIsolationKey& network_isolation_key) = default; + +NetworkIsolationKey& NetworkIsolationKey::operator=( + NetworkIsolationKey&& network_isolation_key) = default; + +std::string NetworkIsolationKey::ToString() const { + if (top_frame_origin_ && !top_frame_origin_->opaque()) + return top_frame_origin_->Serialize(); + return std::string(); +} + +std::string NetworkIsolationKey::ToDebugString() const { + if (!top_frame_origin_) + return "null"; + return top_frame_origin_->GetDebugString(); +} + +bool NetworkIsolationKey::IsFullyPopulated() const { + return top_frame_origin_.has_value(); +} + +bool NetworkIsolationKey::IsTransient() const { + if (!IsFullyPopulated()) + return true; + return top_frame_origin_->opaque(); +} + +} // namespace net diff --git a/chromium/net/base/network_isolation_key.h b/chromium/net/base/network_isolation_key.h new file mode 100644 index 00000000000..ced5858a40c --- /dev/null +++ b/chromium/net/base/network_isolation_key.h @@ -0,0 +1,68 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_ +#define NET_BASE_NETWORK_ISOLATION_KEY_H_ + +#include <string> + +#include "base/macros.h" +#include "base/optional.h" +#include "net/base/net_export.h" +#include "url/origin.h" + +namespace net { + +// Key used to isolate shared network stack resources used by requests based on +// the context on which they were made. +class NET_EXPORT NetworkIsolationKey { + public: + NetworkIsolationKey(const base::Optional<url::Origin>& top_frame_origin); + + // Construct an empty key. + NetworkIsolationKey(); + + NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key); + + ~NetworkIsolationKey(); + + NetworkIsolationKey& operator=( + const NetworkIsolationKey& network_isolation_key); + NetworkIsolationKey& operator=(NetworkIsolationKey&& network_isolation_key); + + bool operator==(const NetworkIsolationKey& other) const { + return top_frame_origin_ == other.top_frame_origin_; + } + + bool operator<(const NetworkIsolationKey& other) const { + return top_frame_origin_ < other.top_frame_origin_; + } + + // TODO(shivanisha): Use feature flags in the below methods to determine which + // parts of the key are being used based on the enabled experiment. + + // Returns the string representation of the key. + std::string ToString() const; + + // Returns string for debugging. Difference from ToString() is that transient + // entries may be distinguishable from each other. + std::string ToDebugString() const; + + // Returns true if all parts of the key are non-empty. + bool IsFullyPopulated() const; + + // Returns true if this key's lifetime is short-lived. It may not make sense + // to persist state to disk related to it (e.g., disk cache). + bool IsTransient() const; + + private: + // The origin of the top frame of the request (if applicable). + base::Optional<url::Origin> top_frame_origin_; + + // TODO(crbug.com/950069): Also add initiator origin to the key. +}; + +} // namespace net + +#endif // NET_BASE_NETWORK_ISOLATION_KEY_H_ diff --git a/chromium/net/base/network_isolation_key_unittest.cc b/chromium/net/base/network_isolation_key_unittest.cc new file mode 100644 index 00000000000..74549a84e7f --- /dev/null +++ b/chromium/net/base/network_isolation_key_unittest.cc @@ -0,0 +1,107 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/network_isolation_key.h" + +#include "base/stl_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace net { + +TEST(NetworkIsolationKeyTest, EmptyKey) { + NetworkIsolationKey key; + EXPECT_FALSE(key.IsFullyPopulated()); + EXPECT_EQ(std::string(), key.ToString()); + EXPECT_TRUE(key.IsTransient()); + EXPECT_EQ("null", key.ToDebugString()); +} + +TEST(NetworkIsolationKeyTest, NonEmptyKey) { + url::Origin origin = url::Origin::Create(GURL("http://a.test/")); + NetworkIsolationKey key(origin); + EXPECT_TRUE(key.IsFullyPopulated()); + EXPECT_EQ(origin.Serialize(), key.ToString()); + EXPECT_FALSE(key.IsTransient()); + EXPECT_EQ("http://a.test", key.ToDebugString()); +} + +TEST(NetworkIsolationKeyTest, OpaqueOriginKey) { + url::Origin origin_data = + url::Origin::Create(GURL("data:text/html,<body>Hello World</body>")); + NetworkIsolationKey key(origin_data); + EXPECT_TRUE(key.IsFullyPopulated()); + EXPECT_EQ(std::string(), key.ToString()); + EXPECT_TRUE(key.IsTransient()); + + // Create another opaque origin, and make sure it has a different debug + // string. + EXPECT_NE( + key.ToDebugString(), + NetworkIsolationKey(origin_data.DeriveNewOpaqueOrigin()).ToDebugString()); +} + +TEST(NetworkIsolationKeyTest, Operators) { + // These are in ascending order. + const NetworkIsolationKey kKeys[] = { + NetworkIsolationKey(), + // Unique origins are still sorted by scheme, so data is before file, and + // file before http. + NetworkIsolationKey( + url::Origin::Create(GURL("data:text/html,<body>Hello World</body>"))), + NetworkIsolationKey(url::Origin::Create(GURL("file:///foo"))), + NetworkIsolationKey(url::Origin::Create(GURL("http://a.test/"))), + NetworkIsolationKey(url::Origin::Create(GURL("http://b.test/"))), + NetworkIsolationKey(url::Origin::Create(GURL("https://a.test/"))), + }; + + for (size_t first = 0; first < base::size(kKeys); ++first) { + NetworkIsolationKey key1 = kKeys[first]; + SCOPED_TRACE(key1.ToDebugString()); + + EXPECT_TRUE(key1 == key1); + EXPECT_FALSE(key1 < key1); + + // Make sure that copying a key doesn't change the results of any operation. + // This check is a bit more interesting with unique origins. + NetworkIsolationKey key1_copy = key1; + EXPECT_TRUE(key1 == key1_copy); + EXPECT_FALSE(key1 < key1_copy); + EXPECT_FALSE(key1_copy < key1); + + for (size_t second = first + 1; second < base::size(kKeys); ++second) { + NetworkIsolationKey key2 = kKeys[second]; + SCOPED_TRACE(key2.ToDebugString()); + + EXPECT_TRUE(key1 < key2); + EXPECT_FALSE(key2 < key1); + EXPECT_FALSE(key1 == key2); + EXPECT_FALSE(key2 == key1); + } + } +} + +TEST(NetworkIsolationKeyTest, UniqueOriginOperators) { + NetworkIsolationKey key1( + url::Origin::Create(GURL("data:text/html,<body>Hello World</body>"))); + NetworkIsolationKey key2( + url::Origin::Create(GURL("data:text/html,<body>Hello World</body>"))); + + EXPECT_TRUE(key1 == key1); + EXPECT_TRUE(key2 == key2); + + // Creating copies shouldn't affect comparison result. + EXPECT_TRUE(NetworkIsolationKey(key1) == NetworkIsolationKey(key1)); + EXPECT_TRUE(NetworkIsolationKey(key2) == NetworkIsolationKey(key2)); + + EXPECT_FALSE(key1 == key2); + EXPECT_FALSE(key2 == key1); + + // Order of Nonces isn't predictable, but they should have an ordering. + EXPECT_TRUE(key1 < key2 || key2 < key1); + EXPECT_TRUE(!(key1 < key2) || !(key2 < key1)); +} + +} // namespace net diff --git a/chromium/net/base/port_util.cc b/chromium/net/base/port_util.cc index f6ab41c8365..7ff334ca1da 100644 --- a/chromium/net/base/port_util.cc +++ b/chromium/net/base/port_util.cc @@ -72,8 +72,8 @@ const int kRestrictedPorts[] = { 548, // AFP (Apple Filing Protocol) 556, // remotefs 563, // nntp+ssl - 587, // stmp? - 601, // ?? + 587, // smtp (rfc6409) + 601, // syslog-conn (rfc3195) 636, // ldap+ssl 993, // ldap+ssl 995, // pop3+ssl diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat index 59db7d0c52f..f81cc8046b8 100644 --- a/chromium/net/base/registry_controlled_domains/effective_tld_names.dat +++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.dat @@ -159,8 +159,13 @@ mil.al net.al org.al -// am : https://en.wikipedia.org/wiki/.am +// am : https://www.amnic.net/policy/en/Policy_EN.pdf am +co.am +com.am +commune.am +net.am +org.am // ao : https://en.wikipedia.org/wiki/.ao // http://www.dns.ao/REGISTR.DOC @@ -585,6 +590,7 @@ slz.br sorocaba.br srv.br taxi.br +tc.br teo.br the.br tmp.br @@ -988,17 +994,16 @@ fm fo // fr : http://www.afnic.fr/ -// domaines descriptifs : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-descriptifs +// domaines descriptifs : https://www.afnic.fr/medias/documents/Cadre_legal/Afnic_Naming_Policy_12122016_VEN.pdf fr -com.fr asso.fr +com.fr +gouv.fr nom.fr prd.fr -presse.fr tm.fr -// domaines sectoriels : http://www.afnic.fr/obtenir/chartes/nommage-fr/annexe-sectoriels +// domaines sectoriels : https://www.afnic.fr/en/products-and-services/the-fr-tld/sector-based-fr-domains-4.html aeroport.fr -assedic.fr avocat.fr avoues.fr cci.fr @@ -1006,7 +1011,6 @@ chambagri.fr chirurgiens-dentistes.fr experts-comptables.fr geometre-expert.fr -gouv.fr greta.fr huissier-justice.fr medecin.fr @@ -5892,17 +5896,15 @@ int.ru mil.ru test.ru -// rw : http://www.nic.rw/cgi-bin/policy.pl +// rw : https://www.ricta.org.rw/sites/default/files/resources/registry_registrar_contract_0.pdf rw -gov.rw -net.rw -edu.rw ac.rw -com.rw co.rw -int.rw +coop.rw +gov.rw mil.rw -gouv.rw +net.rw +org.rw // sa : http://www.nic.net.sa/ sa @@ -6192,34 +6194,33 @@ org.to edu.to mil.to -// subTLDs: https://www.nic.tr/forms/eng/policies.pdf -// and: https://www.nic.tr/forms/politikalar.pdf -// Submitted by <mehmetgurevin@gmail.com> +// tr : https://nic.tr/ +// https://nic.tr/forms/eng/policies.pdf +// https://nic.tr/index.php?USRACTN=PRICELST tr -com.tr -info.tr -biz.tr -net.tr -org.tr -web.tr -gen.tr -tv.tr av.tr -dr.tr bbs.tr -name.tr -tel.tr -gov.tr bel.tr -pol.tr +biz.tr +com.tr +dr.tr +edu.tr +gen.tr +gov.tr +info.tr mil.tr k12.tr -edu.tr kep.tr - +name.tr +net.tr +org.tr +pol.tr +tel.tr +tsk.tr +tv.tr +web.tr // Used by Northern Cyprus nc.tr - // Used by government agencies of Northern Cyprus gov.nc.tr @@ -7942,9 +7943,6 @@ dodge // dog : 2014-12-04 Binky Moon, LLC dog -// doha : 2014-09-18 Communications Regulatory Authority (CRA) -doha - // domains : 2013-10-17 Binky Moon, LLC domains @@ -10693,6 +10691,10 @@ ltd.ua // Submitted by Przemyslaw Plewa <it-admin@domena.pl> beep.pl +// alboto.ca : http://alboto.ca +// Submitted by Anton Avramov <avramov@alboto.ca> +barsy.ca + // Alces Software Ltd : http://alces-software.com // Submitted by Mark J. Titorenko <mark.titorenko@alces-software.com> *.compute.estate @@ -10829,6 +10831,7 @@ myasustor.com // Automattic Inc. : https://automattic.com/ // Submitted by Alex Concha <alex.concha@automattic.com> go-vip.co +go-vip.net wpcomstaging.com // AVM : https://avm.de @@ -10840,10 +10843,18 @@ myfritz.net *.awdev.ca *.advisor.ws +// b-data GmbH : https://www.b-data.io +// Submitted by Olivier Benz <olivier.benz@b-data.ch> +b-data.io + // backplane : https://www.backplane.io // Submitted by Anthony Voutas <anthony@backplane.io> backplaneapp.io +// Banzai Cloud +// Submitted by Gabor Kozma <info@banzaicloud.com> +app.banzaicloud.io + // BetaInABox // Submitted by Adrian <adrian@betainabox.com> betainabox.com @@ -10879,6 +10890,7 @@ browsersafetymark.io // Bytemark Hosting : https://www.bytemark.co.uk // Submitted by Paul Cammish <paul.cammish@bytemark.co.uk> +uk0.bigv.io dh.bytemark.co.uk vm.bytemark.co.uk @@ -10886,6 +10898,12 @@ vm.bytemark.co.uk // Submitted by Marcus Popp <admin@callidomus.com> mycd.eu +// Carrd : https://carrd.co +// Submitted by AJ <aj@carrd.co> +carrd.co +crd.co +uwu.ai + // CentralNic : http://www.centralnic.com/names/domains // Submitted by registry <gavin.brown@centralnic.com> ae.org @@ -10947,6 +10965,10 @@ certmgr.org // Submitted by Alex Stoddard <alex.stoddard@citrix.com> xenapponazure.com +// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ +// Submitted by Rishabh Nambiar <rishabh.nambiar@discourse.org> +discourse.group + // ClearVox : http://www.clearvox.nl/ // Submitted by Leon Rowland <leon@clearvox.nl> virtueeldomein.nl @@ -10955,10 +10977,16 @@ virtueeldomein.nl // Submitted by Quentin Adam <noc@clever-cloud.com> cleverapps.io +// Clerk : https://www.clerk.dev +// Submitted by Colin Sidoti <colin@clerk.dev> +*.lcl.dev +*.stg.dev + // Cloud66 : https://www.cloud66.com/ // Submitted by Khash Sajadi <khash@cloud66.com> c66.me cloud66.ws +cloud66.zone // CloudAccess.net : https://www.cloudaccess.net/ // Submitted by Pawel Panek <noc@cloudaccess.net> @@ -10973,6 +11001,14 @@ cloudaccess.net cloudcontrolled.com cloudcontrolapp.com +// Cloudflare, Inc. : https://www.cloudflare.com/ +// Submitted by Jake Riesterer <publicsuffixlist@cloudflare.com> +workers.dev + +// Clovyr : https://clovyr.io +// Submitted by Patrick Nielsen <patrick@clovyr.io> +wnext.app + // co.ca : http://registry.co.ca/ co.ca @@ -11456,6 +11492,11 @@ e4.cz // Submitted by Thomas Cottier <thomas.cottier@enalean.com> mytuleap.com +// ECG Robotics, Inc: https://ecgrobotics.org +// Submitted by <frc1533@ecgrobotics.org> +onred.one +staging.onred.one + // Enonic : http://enonic.com/ // Submitted by Erik Kaareng-Sunde <esu@enonic.com> enonic.io @@ -11704,6 +11745,15 @@ futuremailing.at // Submitted by David Illsley <david.illsley@digital.cabinet-office.gov.uk> service.gov.uk +// Gehirn Inc. : https://www.gehirn.co.jp/ +// Submitted by Kohei YOSHIDA <tech@gehirn.co.jp> +gehirn.ne.jp +usercontent.jp + +// Gentlent, Limited : https://www.gentlent.com +// Submitted by Tom Klein <tklein@gentlent.com> +lab.ms + // GitHub, Inc. // Submitted by Patrick Toomey <security@github.com> github.io @@ -11713,6 +11763,15 @@ githubusercontent.com // Submitted by Alex Hanselka <alex@gitlab.com> gitlab.io +// Glitch, Inc : https://glitch.com +// Submitted by Mads Hartmann <mads@glitch.com> +glitch.me + +// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ +// Submitted by Tom Whitwell <tom.whitwell@digital.cabinet-office.gov.uk> +cloudapps.digital +london.cloudapps.digital + // UKHomeOffice : https://www.gov.uk/government/organisations/home-office // Submitted by Jon Shanks <jon.shanks@digital.homeoffice.gov.uk> homeoffice.gov.uk @@ -11816,6 +11875,14 @@ publishproxy.com withgoogle.com withyoutube.com +// Hakaran group: http://hakaran.cz +// Submited by Arseniy Sokolov <security@hakaran.cz> +fin.ci +free.hr +caa.li +ua.rs +conf.se + // Hashbang : https://hashbang.sh hashbang.sh @@ -11841,8 +11908,25 @@ ravendb.me development.run ravendb.run +// HOSTBIP REGISTRY : https://www.hostbip.com/ +// Submitted by Atanunu Igbunuroghene <publicsuffixlist@hostbip.com> +bpl.biz +orx.biz +ng.city +ng.ink +biz.gl +col.ng +gen.ng +ltd.ng +sch.so + +// Häkkinen.fi +// Submitted by Eero Häkkinen <Eero+psl@Häkkinen.fi> +häkkinen.fi + // Ici la Lune : http://www.icilalune.com/ // Submitted by Simon Morvan <simon@icilalune.com> +*.moonscale.io moonscale.net // iki.fi @@ -11930,6 +12014,11 @@ myjino.ru // Submitted by Stefan Keim <admin@js.org> js.org +// KaasHosting : http://www.kaashosting.nl/ +// Submitted by Wouter Bakker <hostmaster@kaashosting.nl> +kaas.gg +khplay.nl + // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl <postmaster@keymachine.de> keymachine.de @@ -11977,10 +12066,23 @@ linkitools.space linkyard.cloud linkyard-cloud.ch +// Linode : https://linode.com +// Submitted by <security@linode.com> +members.linode.com +nodebalancer.linode.com + // LiquidNet Ltd : http://www.liquidnetlimited.com/ // Submitted by Victor Velchev <admin@liquidnetlimited.com> we.bs +// Log'in Line : https://www.loginline.com/ +// Submitted by Rémi Mach <remi.mach@loginline.com> +loginline.app +loginline.dev +loginline.io +loginline.services +loginline.site + // LubMAN UMCS Sp. z o.o : https://lubman.pl/ // Submitted by Ireneusz Maliszewski <ireneusz.maliszewski@lubman.pl> krasnik.pl @@ -12080,6 +12182,30 @@ net.ru org.ru pp.ru +// Nabu Casa : https://www.nabucasa.com +// Submitted by Paulus Schoutsen <infra@nabucasa.com> +ui.nabu.casa + +// Names.of.London : https://names.of.london/ +// Submitted by James Stevens <registry@names.of.london> or <james@jrcs.net> +pony.club +of.fashion +on.fashion +of.football +in.london +of.london +for.men +and.mom +for.mom +for.one +for.sale +of.work +to.work + +// NCTU.ME : https://nctu.me/ +// Submitted by Tocknicsu <admin@nctu.me> +nctu.me + // Netlify : https://www.netlify.com // Submitted by Jessica Parsons <jessica@netlify.com> bitballoon.com @@ -12361,6 +12487,10 @@ on-web.fr // *.platform.sh *.platformsh.site +// Positive Codes Technology Company : http://co.bn/faq.html +// Submitted by Zulfais <pc@co.bn> +co.bn + // prgmr.com : https://prgmr.com/ // Submitted by Sarah Newman <owner@prgmr.com> xen.prgmr.com @@ -12369,6 +12499,14 @@ xen.prgmr.com // Submitted by registry <lendl@nic.at> priv.at +// privacytools.io : https://www.privacytools.io/ +// Submitted by Jonah Aragon <jonah@privacytools.io> +prvcy.page + +// Protocol Labs : https://protocol.ai/ +// Submitted by Michael Burns <noc@protocol.ai> +*.dweb.link + // Protonet GmbH : http://protonet.io // Submitted by Martin Meier <admin@protonet.io> protonet.io @@ -12410,6 +12548,11 @@ vaporcloud.io rackmaze.com rackmaze.net +// Rancher Labs, Inc : https://rancher.com +// Submitted by Vincent Fiduccia <domains@rancher.com> +*.on-rancher.cloud +*.on-rio.io + // Read The Docs, Inc : https://www.readthedocs.org // Submitted by David Fischer <team@readthedocs.org> readthedocs.io @@ -12418,6 +12561,16 @@ readthedocs.io // Submitted by Tim Kramer <tkramer@rhcloud.com> rhcloud.com +// Render : https://render.com +// Submitted by Anurag Goel <dev@render.com> +app.render.com +onrender.com + +// Repl.it : https://repl.it +// Submitted by Mason Clayton <mason@repl.it> +repl.co +repl.run + // Resin.io : https://resin.io // Submitted by Tim Perry <tim@resin.io> resindevice.io @@ -12433,6 +12586,10 @@ wellbeingzone.eu ptplus.fit wellbeingzone.co.uk +// Rochester Institute of Technology : http://www.rit.edu/ +// Submitted by Jennifer Herting <jchits@rit.edu> +git-pages.rit.edu + // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia <asheesh@sandstorm.io> sandcats.io @@ -12482,6 +12639,10 @@ shiftedit.io // Submitted by Alex Bowers <alex@shopblocks.com> myshopblocks.com +// Siemens Mobility GmbH +// Submitted by Oliver Graebner <security@mo-siemens.io> +mo-siemens.io + // SinaAppEngine : http://sae.sina.com.cn/ // Submitted by SinaAppEngine <saesupport@sinacloud.com> 1kapp.com @@ -12500,6 +12661,10 @@ bounty-full.com alpha.bounty-full.com beta.bounty-full.com +// Stackhero : https://www.stackhero.io +// Submitted by Adrien Gillon <adrien+public-suffix-list@stackhero.io> +stackhero-network.com + // staticland : https://static.land // Submitted by Seth Vincent <sethvincent@gmail.com> static.land @@ -12531,6 +12696,11 @@ storj.farm // Submitted by Silke Hofstra <syscom@snt.utwente.nl> utwente.io +// Student-Run Computing Facility : https://www.srcf.net/ +// Submitted by Edwin Balani <sysadmins@srcf.net> +soc.srcf.net +user.srcf.net + // Sub 6 Limited: http://www.sub6.com // Submitted by Dan Miller <dm@sub6.com> temp-dns.com @@ -12540,6 +12710,10 @@ temp-dns.com applicationcloud.io scapp.io +// Syncloud : https://syncloud.org +// Submitted by Boris Rybalkin <syncloud@syncloud.it> +syncloud.it + // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng <ronyweng@synology.com> diskstation.me @@ -12568,6 +12742,10 @@ gdynia.pl med.pl sopot.pl +// Teckids e.V. : https://www.teckids.org +// Submitted by Dominik George <dominik.george@teckids.org> +edugit.org + // Telebit : https://telebit.cloud // Submitted by AJ ONeal <aj@telebit.cloud> telebit.app @@ -12580,11 +12758,17 @@ gwiddle.co.uk // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden <adi@thingdust.com> +thingdustdata.com cust.dev.thingdust.io cust.disrec.thingdust.io cust.prod.thingdust.io cust.testing.thingdust.io +// Tlon.io : https://tlon.io +// Submitted by Mark Staarink <mark@tlon.io> +arvo.network +azimuth.network + // TownNews.com : http://www.townnews.com // Submitted by Dustin Ward <dward@townnews.com> bloxcms.com @@ -12671,6 +12855,14 @@ router.management // Submitted by Adnan RIHAN <hostmaster@v-info.info> v-info.info +// Voorloper.com: https://voorloper.com +// Submitted by Nathan van Bakel <info@voorloper.com> +voorloper.cloud + +// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com +// Submitted by Masayuki Note <masa@blade.wafflecell.com> +wafflecell.com + // WeDeploy by Liferay, Inc. : https://www.wedeploy.com // Submitted by Henrique Vicente <security@wedeploy.com> wedeploy.io @@ -12737,6 +12929,13 @@ now.sh // Submitted by Martin Angelov <martin@zine.bg> bss.design +// Zitcom A/S : https://www.zitcom.dk +// Submitted by Emil Stahl <esp@zitcom.dk> +basicserver.io +virtualserver.io +site.builder.nu +enterprisecloud.nu + // Zone.id : https://zone.id/ // Submitted by Su Hendro <admin@zone.id> zone.id diff --git a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf index 56f3713b15e..e8bd23fa812 100644 --- a/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf +++ b/chromium/net/base/registry_controlled_domains/effective_tld_names.gperf @@ -293,6 +293,7 @@ anan.nagano.jp, 0 anan.tokushima.jp, 0 anani.br, 0 ancona.it, 0 +and.mom, 4 and.museum, 0 andasuolo.no, 0 andebu.no, 0 @@ -340,9 +341,11 @@ apartments, 0 api.stdlib.com, 4 apigee.io, 4 app, 0 +app.banzaicloud.io, 4 app.lmpm.com, 4 app.os.fedoraproject.org, 4 app.os.stg.fedoraproject.org, 4 +app.render.com, 4 appchizi.com, 4 apple, 0 applicationcloud.io, 4 @@ -405,6 +408,7 @@ arts.nf, 0 arts.ro, 0 arts.ve, 0 artsandcrafts.museum, 0 +arvo.network, 4 as, 0 as.us, 0 asago.hyogo.jp, 0 @@ -442,7 +446,6 @@ aso.kumamoto.jp, 0 ass.km, 0 assabu.hokkaido.jp, 0 assassination.museum, 0 -assedic.fr, 0 assisi.museum, 0 assn.lk, 0 asso.bj, 0 @@ -521,11 +524,13 @@ ayase.kanagawa.jp, 0 az, 0 az.us, 0 azerbaijan.su, 4 +azimuth.network, 4 azumino.nagano.jp, 0 azure, 0 azure-mobile.net, 4 azurecontainer.io, 4 azurewebsites.net, 4 +b-data.io, 4 b.bg, 0 b.br, 0 b.se, 0 @@ -580,6 +585,7 @@ barreau.bj, 0 barrel-of-knowledge.info, 4 barrell-of-knowledge.info, 4 barsy.bg, 4 +barsy.ca, 4 barsy.club, 4 barsy.co.uk, 4 barsy.de, 4 @@ -610,6 +616,7 @@ baseball.museum, 0 basel.museum, 0 bashkiria.ru, 4 bashkiria.su, 4 +basicserver.io, 4 basilicata.it, 0 basketball, 0 baths.museum, 0 @@ -708,6 +715,7 @@ biz.bb, 0 biz.cy, 0 biz.dk, 4 biz.et, 0 +biz.gl, 4 biz.id, 0 biz.ki, 0 biz.ls, 0 @@ -873,6 +881,7 @@ boxfuse.io, 4 bozen-sudtirol.it, 0 bozen-suedtirol.it, 0 bozen.it, 0 +bpl.biz, 4 bplaced.com, 4 bplaced.de, 4 bplaced.net, 4 @@ -961,6 +970,7 @@ ca.it, 0 ca.na, 0 ca.us, 0 caa.aero, 0 +caa.li, 4 cab, 0 cable-modem.org, 4 cadaques.museum, 0 @@ -1005,6 +1015,7 @@ careers, 0 cargo.aero, 0 carrara-massa.it, 0 carraramassa.it, 0 +carrd.co, 4 carrier.museum, 0 cars, 0 cartier, 0 @@ -1234,9 +1245,11 @@ cloud.fedoraproject.org, 4 cloud.goog, 4 cloud.metacentrum.cz, 4 cloud66.ws, 4 +cloud66.zone, 4 cloudaccess.host, 4 cloudaccess.net, 4 cloudapp.net, 4 +cloudapps.digital, 4 cloudcontrolapp.com, 4 cloudcontrolled.com, 4 cloudeity.net, 4 @@ -1273,10 +1286,12 @@ cnt.br, 0 co, 0 co.ae, 0 co.ag, 0 +co.am, 0 co.ao, 0 co.at, 0 co.bb, 0 co.bi, 0 +co.bn, 4 co.business, 4 co.bw, 0 co.ca, 4 @@ -1352,6 +1367,7 @@ codespot.com, 4 cody.museum, 0 coffee, 0 cog.mi.us, 0 +col.ng, 4 coldwar.museum, 0 collection.museum, 0 college, 0 @@ -1367,6 +1383,7 @@ com.af, 0 com.ag, 0 com.ai, 0 com.al, 0 +com.am, 0 com.ar, 0 com.au, 0 com.aw, 0 @@ -1464,7 +1481,6 @@ com.qa, 0 com.re, 0 com.ro, 0 com.ru, 4 -com.rw, 0 com.sa, 0 com.sb, 0 com.sc, 0 @@ -1498,6 +1514,7 @@ com.ws, 0 com.zm, 0 comcast, 0 commbank, 0 +commune.am, 0 communication.museum, 0 communications.museum, 0 community, 0 @@ -1516,6 +1533,7 @@ comsec, 0 condos, 0 conf.au, 0 conf.lv, 0 +conf.se, 4 conference.aero, 0 construction, 0 consulado.st, 0 @@ -1539,6 +1557,7 @@ coop.km, 0 coop.mv, 0 coop.mw, 0 coop.py, 0 +coop.rw, 0 coop.tt, 0 cooperativa.bo, 0 copenhagen.museum, 0 @@ -1563,6 +1582,7 @@ cr.ua, 0 crafting.xyz, 4 crafts.museum, 0 cranbrook.museum, 0 +crd.co, 4 creation.museum, 0 credit, 0 creditcard, 0 @@ -1721,6 +1741,7 @@ dinosaur.museum, 0 direct, 0 directory, 0 discount, 0 +discourse.group, 4 discover, 0 discovery.museum, 0 dish, 0 @@ -1761,7 +1782,6 @@ does-it.net, 4 doesntexist.com, 4 doesntexist.org, 4 dog, 0 -doha, 0 dolls.museum, 0 domains, 0 dominic.ua, 0 @@ -1810,6 +1830,7 @@ dvag, 0 dvr, 0 dvrcam.info, 4 dvrdns.org, 4 +dweb.link, 6 dy.fi, 4 dyn-berlin.de, 4 dyn-ip24.de, 4 @@ -1980,7 +2001,6 @@ edu.py, 0 edu.qa, 0 edu.rs, 0 edu.ru, 0 -edu.rw, 0 edu.sa, 0 edu.sb, 0 edu.sc, 0 @@ -2010,6 +2030,7 @@ education, 0 education.museum, 0 educational.museum, 0 educator.aero, 0 +edugit.org, 4 edunet.tn, 0 ee, 0 ee.eu.org, 4 @@ -2066,6 +2087,7 @@ eniwa.hokkaido.jp, 0 enna.it, 0 enonic.io, 4 ens.tn, 0 +enterprisecloud.nu, 4 enterprises, 0 entertainment.aero, 0 entomology.museum, 0 @@ -2217,6 +2239,7 @@ filegear.me, 4 film, 0 film.hu, 0 film.museum, 0 +fin.ci, 4 fin.ec, 0 fin.tn, 0 final, 0 @@ -2292,6 +2315,10 @@ for-more.biz, 4 for-our.info, 4 for-some.biz, 4 for-the.biz, 4 +for.men, 4 +for.mom, 4 +for.one, 4 +for.sale, 4 force.museum, 0 ford, 0 forde.no, 0 @@ -2323,6 +2350,7 @@ frankfurt.museum, 0 franziskaner.museum, 0 fredrikstad.no, 0 free, 0 +free.hr, 4 freebox-os.com, 4 freebox-os.fr, 4 freeboxos.com, 4 @@ -2530,10 +2558,12 @@ gea, 0 geek.nz, 0 geekgalaxy.com, 4 geelvinck.museum, 0 +gehirn.ne.jp, 4 geisei.kochi.jp, 0 gemological.museum, 0 gen.in, 0 gen.mi.us, 0 +gen.ng, 4 gen.nz, 0 gen.tr, 0 genkai.saga.jp, 0 @@ -2566,6 +2596,7 @@ ginan.gifu.jp, 0 ginowan.okinawa.jp, 0 ginoza.okinawa.jp, 0 giske.no, 0 +git-pages.rit.edu, 4 git-repos.de, 4 github.io, 4 githubusercontent.com, 4 @@ -2585,6 +2616,7 @@ glass.museum, 0 gle, 0 gleeze.com, 4 gliding.aero, 0 +glitch.me, 4 gliwice.pl, 4 global, 0 global.prod.fastly.net, 4 @@ -2602,6 +2634,7 @@ gmx, 0 gn, 0 gniezno.pl, 0 go-vip.co, 4 +go-vip.net, 4 go.ci, 0 go.cr, 0 go.dyndns.org, 4 @@ -2676,7 +2709,6 @@ gouv.fr, 0 gouv.ht, 0 gouv.km, 0 gouv.ml, 0 -gouv.rw, 0 gouv.sn, 0 gov, 0 gov.ac, 0 @@ -3297,6 +3329,7 @@ in-vpn.net, 4 in-vpn.org, 4 in.eu.org, 4 in.futurecms.at, 6 +in.london, 4 in.na, 0 in.net, 4 in.ni, 0 @@ -3397,7 +3430,6 @@ int.mw, 0 int.ni, 0 int.pt, 0 int.ru, 0 -int.rw, 0 int.tj, 0 int.tt, 0 int.ve, 0 @@ -3709,6 +3741,7 @@ k12.vt.us, 0 k12.wa.us, 0 k12.wi.us, 0 k12.wy.us, 0 +kaas.gg, 4 kadena.okinawa.jp, 0 kadogawa.miyazaki.jp, 0 kadoma.osaka.jp, 0 @@ -3885,6 +3918,7 @@ kharkov.ua, 0 kherson.ua, 0 khmelnitskiy.ua, 0 khmelnytskyi.ua, 0 +khplay.nl, 4 ki, 0 kia, 0 kibichuo.okayama.jp, 0 @@ -4132,6 +4166,7 @@ la, 0 la-spezia.it, 0 la.us, 0 laakesvuemie.no, 0 +lab.ms, 4 labor.museum, 0 labour.museum, 0 lacaixa, 0 @@ -4176,6 +4211,7 @@ lazio.it, 0 lb, 0 lc, 0 lc.it, 0 +lcl.dev, 6 lcube-server.de, 4 lds, 0 le.it, 0 @@ -4325,6 +4361,11 @@ locus, 0 lodi.it, 0 lodingen.no, 0 loft, 0 +loginline.app, 4 +loginline.dev, 4 +loginline.io, 4 +loginline.services, 4 +loginline.site, 4 loginto.me, 4 logistics.aero, 0 logoip.com, 4 @@ -4336,6 +4377,7 @@ lombardia.it, 0 lombardy.it, 0 lomza.pl, 0 london, 0 +london.cloudapps.digital, 4 london.museum, 0 londrina.br, 0 loppa.no, 0 @@ -4365,6 +4407,7 @@ ltd.cy, 0 ltd.gi, 0 ltd.hk, 4 ltd.lk, 0 +ltd.ng, 4 ltd.ua, 4 ltd.uk, 0 ltda, 0 @@ -4554,6 +4597,7 @@ melbourne, 0 meldal.no, 0 melhus.no, 0 meloy.no, 0 +members.linode.com, 4 meme, 0 memorial, 0 memorial.museum, 0 @@ -4770,6 +4814,7 @@ mn.it, 0 mn.us, 0 mo, 0 mo-i-rana.no, 0 +mo-siemens.io, 4 mo.cn, 0 mo.it, 0 mo.us, 0 @@ -4814,6 +4859,7 @@ monza.it, 0 monzabrianza.it, 0 monzaebrianza.it, 0 monzaedellabrianza.it, 0 +moonscale.io, 6 moonscale.net, 4 mopar, 0 mordovia.ru, 4 @@ -5103,6 +5149,7 @@ nba, 0 nc, 0 nc.tr, 0 nc.us, 0 +nctu.me, 4 nd.us, 0 ne, 0 ne.jp, 0 @@ -5134,6 +5181,7 @@ net.af, 0 net.ag, 0 net.ai, 0 net.al, 0 +net.am, 0 net.ar, 0 net.au, 0 net.az, 0 @@ -5284,7 +5332,9 @@ nfl, 0 nflfan.org, 4 nfshost.com, 4 ng, 0 +ng.city, 4 ng.eu.org, 4 +ng.ink, 4 ngo, 0 ngo.lk, 0 ngo.ph, 0 @@ -5370,6 +5420,7 @@ nobeoka.miyazaki.jp, 0 noboribetsu.hokkaido.jp, 0 noda.chiba.jp, 0 noda.iwate.jp, 0 +nodebalancer.linode.com, 4 nodum.co, 4 nodum.io, 4 nogata.fukuoka.jp, 0 @@ -5548,7 +5599,11 @@ odessa.ua, 0 odo.br, 0 oe.yamagata.jp, 0 of.by, 0 +of.fashion, 4 +of.football, 4 +of.london, 4 of.no, 0 +of.work, 4 off, 0 off.ai, 0 office, 0 @@ -5641,9 +5696,12 @@ omotego.fukushima.jp, 0 omura.nagasaki.jp, 0 omuta.fukuoka.jp, 0 on-aptible.com, 4 +on-rancher.cloud, 6 +on-rio.io, 6 on-the-web.tv, 4 on-web.fr, 4 on.ca, 0 +on.fashion, 4 onagawa.miyagi.jp, 0 one, 0 ong, 0 @@ -5661,6 +5719,8 @@ ono.fukushima.jp, 0 ono.hyogo.jp, 0 onojo.fukuoka.jp, 0 onomichi.hiroshima.jp, 0 +onred.one, 4 +onrender.com, 4 ontario.museum, 0 onthewifi.com, 4 onyourside, 0 @@ -5704,6 +5764,7 @@ org.af, 0 org.ag, 0 org.ai, 0 org.al, 0 +org.am, 0 org.ar, 0 org.au, 0 org.az, 0 @@ -5808,6 +5869,7 @@ org.qa, 0 org.ro, 0 org.rs, 0 org.ru, 4 +org.rw, 0 org.sa, 0 org.sb, 0 org.sc, 0 @@ -5851,6 +5913,7 @@ orkdal.no, 0 orland.no, 0 orskog.no, 0 orsta.no, 0 +orx.biz, 4 os.hedmark.no, 0 os.hordaland.no, 0 osaka, 0 @@ -6093,6 +6156,7 @@ pomorskie.pl, 0 pomorze.pl, 0 poniatowa.pl, 4 ponpes.id, 0 +pony.club, 4 pordenone.it, 0 porn, 0 porsanger.no, 0 @@ -6133,7 +6197,6 @@ press.ma, 0 press.museum, 0 press.se, 0 presse.ci, 0 -presse.fr, 0 presse.km, 0 presse.ml, 0 pri.ee, 0 @@ -6174,6 +6237,7 @@ protonet.io, 4 pru, 0 prudential, 0 pruszkow.pl, 0 +prvcy.page, 4 przeworsk.pl, 0 ps, 0 psc.br, 0 @@ -6306,6 +6370,8 @@ rentals, 0 rep.kp, 0 repair, 0 repbody.aero, 0 +repl.co, 4 +repl.run, 4 report, 0 republican, 0 res.aero, 0 @@ -6628,6 +6694,7 @@ sch.ly, 0 sch.ng, 0 sch.qa, 0 sch.sa, 0 +sch.so, 4 sch.uk, 2 sch.zm, 0 schaeffler, 0 @@ -6894,6 +6961,7 @@ singles, 0 siracusa.it, 0 sirdal.no, 0 site, 0 +site.builder.nu, 4 siteleaf.net, 4 sites.static.land, 4 sj, 0 @@ -6949,6 +7017,7 @@ so.gov.pl, 0 so.it, 0 sobetsu.hokkaido.jp, 0 soc.lk, 0 +soc.srcf.net, 4 soccer, 0 sochi.su, 4 social, 0 @@ -7031,9 +7100,11 @@ ss.it, 0 ssl.origin.cdn77-secure.org, 4 st, 0 st.no, 0 +stackhero-network.com, 4 stada, 0 stadt.museum, 0 stage.nodeart.io, 4 +staging.onred.one, 4 stalbans.museum, 0 stalowa-wola.pl, 0 stange.no, 0 @@ -7062,6 +7133,7 @@ steam.museum, 0 steiermark.museum, 0 steigen.no, 0 steinkjer.no, 0 +stg.dev, 6 stjohn.museum, 0 stjordal.no, 0 stjordalshalsen.no, 0 @@ -7156,6 +7228,7 @@ sydney, 0 sydney.museum, 0 sykkylven.no, 0 symantec, 0 +syncloud.it, 4 syno-ds.de, 4 synology-diskstation.de, 4 synology-ds.de, 4 @@ -7279,6 +7352,7 @@ tax, 0 taxi, 0 taxi.br, 0 tc, 0 +tc.br, 0 tci, 0 tcm.museum, 0 tcp4.me, 4 @@ -7334,6 +7408,7 @@ theater, 0 theater.museum, 0 theatre, 0 theworkpc.com, 4 +thingdustdata.com, 4 thruhere.net, 4 tiaa, 0 tickets, 0 @@ -7378,6 +7453,7 @@ to, 0 to.gov.br, 0 to.it, 0 to.leg.br, 4 +to.work, 4 toba.mie.jp, 0 tobe.ehime.jp, 0 tobetsu.hokkaido.jp, 0 @@ -7562,6 +7638,7 @@ trv, 0 trysil.no, 0 ts.it, 0 tselinograd.su, 4 +tsk.tr, 0 tsu.mie.jp, 0 tsubame.niigata.jp, 0 tsubata.ishikawa.jp, 0 @@ -7636,6 +7713,7 @@ u.se, 0 u2-local.xnbay.com, 4 u2.xnbay.com, 4 ua, 0 +ua.rs, 4 ubank, 0 ube.yamaguchi.jp, 0 uber.space, 4 @@ -7659,6 +7737,7 @@ ug, 0 ug.gov.pl, 0 ugim.gov.pl, 0 uhren.museum, 0 +ui.nabu.casa, 4 uji.kyoto.jp, 0 ujiie.tochigi.jp, 0 ujitawara.kyoto.jp, 0 @@ -7666,6 +7745,7 @@ uk, 0 uk.com, 4 uk.eu.org, 4 uk.net, 4 +uk0.bigv.io, 4 uki.kumamoto.jp, 0 ukiha.fukuoka.jp, 0 uklugs.org, 4 @@ -7735,6 +7815,8 @@ uscountryestate.museum, 0 usculture.museum, 0 usdecorativearts.museum, 0 user.party.eus, 4 +user.srcf.net, 4 +usercontent.jp, 4 usgarden.museum, 0 ushiku.ibaraki.jp, 0 ushistory.museum, 0 @@ -7756,6 +7838,7 @@ utwente.io, 4 uvic.museum, 0 uw.gov.pl, 0 uwajima.ehime.jp, 0 +uwu.ai, 4 uy, 0 uy.com, 4 uz, 0 @@ -7871,6 +7954,7 @@ virgin, 0 virginia.museum, 0 virtual-user.de, 4 virtual.museum, 0 +virtualserver.io, 4 virtualuser.de, 4 virtueeldomein.nl, 4 virtuel.museum, 0 @@ -7899,6 +7983,7 @@ volkswagen, 0 vologda.su, 4 volvo, 0 volyn.ua, 0 +voorloper.cloud, 4 voss.no, 0 vossevangen.no, 0 vote, 0 @@ -7922,6 +8007,7 @@ wa.edu.au, 0 wa.gov.au, 0 wa.us, 0 wada.nagano.jp, 0 +wafflecell.com, 4 wajiki.tokushima.jp, 0 wajima.ishikawa.jp, 0 wakasa.fukui.jp, 0 @@ -8024,11 +8110,13 @@ wlocl.pl, 0 wloclawek.pl, 0 wme, 0 wmflabs.org, 4 +wnext.app, 4 wodzislaw.pl, 0 wolomin.pl, 0 wolterskluwer, 0 woodside, 0 work, 0 +workers.dev, 4 workinggroup.aero, 0 workisboring.com, 4 works, 0 @@ -8232,6 +8320,7 @@ xn--hcesuolo-7ya35b.no, 0 xn--hery-ira.nordland.no, 0 xn--hery-ira.xn--mre-og-romsdal-qqb.no, 0 xn--hgebostad-g3a.no, 0 +xn--hkkinen-5wa.fi, 4 xn--hmmrfeasta-s4ac.no, 0 xn--hnefoss-q1a.no, 0 xn--hobl-ira.no, 0 diff --git a/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc b/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc index 1d23d6b0d9e..598feda5d3d 100644 --- a/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc +++ b/chromium/net/base/registry_controlled_domains/registry_controlled_domain_unittest.cc @@ -363,12 +363,22 @@ TEST_F(RegistryControlledDomainTest, TestSameDomainOrHost) { "http://..b.x.com/file.html")); // x.com EXPECT_TRUE(CompareDomains("http://intranet/file.html", "http://intranet/file.html")); // intranet + EXPECT_FALSE(CompareDomains("http://intranet1/file.html", + "http://intranet2/file.html")); // intranet + EXPECT_TRUE(CompareDomains( + "http://intranet1.corp.example.com/file.html", + "http://intranet2.corp.example.com/file.html")); // intranet EXPECT_TRUE(CompareDomains("http://127.0.0.1/file.html", "http://127.0.0.1/file.html")); // 127.0.0.1 EXPECT_FALSE(CompareDomains("http://192.168.0.1/file.html", // 192.168.0.1 "http://127.0.0.1/file.html")); // 127.0.0.1 EXPECT_FALSE(CompareDomains("file:///C:/file.html", "file:///C:/file.html")); // no host + + // The trailing dot means different sites - see also + // https://github.com/mikewest/sec-metadata/issues/15. + EXPECT_FALSE( + CompareDomains("https://foo.example.com", "https://foo.example.com.")); } TEST_F(RegistryControlledDomainTest, TestDefaultData) { diff --git a/chromium/net/base/upload_data_stream.cc b/chromium/net/base/upload_data_stream.cc index 193872e63c8..6804a1e794f 100644 --- a/chromium/net/base/upload_data_stream.cc +++ b/chromium/net/base/upload_data_stream.cc @@ -15,26 +15,24 @@ namespace net { namespace { -std::unique_ptr<base::Value> NetLogInitEndInfoCallback( - int result, - int total_size, - bool is_chunked, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - - dict->SetInteger("net_error", result); - dict->SetInteger("total_size", total_size); - dict->SetBoolean("is_chunked", is_chunked); - return std::move(dict); +base::Value NetLogInitEndInfoCallback(int result, + int total_size, + bool is_chunked, + NetLogCaptureMode /* capture_mode */) { + base::Value dict(base::Value::Type::DICTIONARY); + + dict.SetIntKey("net_error", result); + dict.SetIntKey("total_size", total_size); + dict.SetBoolKey("is_chunked", is_chunked); + return dict; } -std::unique_ptr<base::Value> NetLogReadInfoCallback( - int current_position, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); +base::Value NetLogReadInfoCallback(int current_position, + NetLogCaptureMode /* capture_mode */) { + base::Value dict(base::Value::Type::DICTIONARY); - dict->SetInteger("current_position", current_position); - return std::move(dict); + dict.SetIntKey("current_position", current_position); + return dict; } } // namespace diff --git a/chromium/net/base/url_util.cc b/chromium/net/base/url_util.cc index 3fe45e9c7b5..d8287fc8607 100644 --- a/chromium/net/base/url_util.cc +++ b/chromium/net/base/url_util.cc @@ -15,6 +15,7 @@ #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" #include "net/base/escape.h" #include "net/base/ip_address.h" #include "net/base/registry_controlled_domains/registry_controlled_domain.h" @@ -37,6 +38,23 @@ bool IsNormalizedLocalhostTLD(const std::string& host) { return base::EndsWith(host, ".localhost", base::CompareCase::SENSITIVE); } +// Helper function used by GetIdentityFromURL. If |escaped_text| can be "safely +// unescaped" to a valid UTF-8 string, return that string, as UTF-16. Otherwise, +// convert it as-is to UTF-16. "Safely unescaped" is defined as having no +// escaped character between '0x00' and '0x1F', inclusive. +base::string16 UnescapeIdentityString(base::StringPiece escaped_text) { + std::string unescaped_text; + if (UnescapeBinaryURLComponentSafe( + escaped_text, false /* fail_on_path_separators */, &unescaped_text)) { + base::string16 result; + if (base::UTF8ToUTF16(unescaped_text.data(), unescaped_text.length(), + &result)) { + return result; + } + } + return base::UTF8ToUTF16(escaped_text); +} + } // namespace GURL AppendQueryParameter(const GURL& url, @@ -384,14 +402,15 @@ GURL ChangeWebSocketSchemeToHttpScheme(const GURL& url) { void GetIdentityFromURL(const GURL& url, base::string16* username, base::string16* password) { - UnescapeRule::Type flags = - UnescapeRule::SPACES | UnescapeRule::PATH_SEPARATORS | - UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS; - *username = UnescapeAndDecodeUTF8URLComponent(url.username(), flags); - *password = UnescapeAndDecodeUTF8URLComponent(url.password(), flags); + *username = UnescapeIdentityString(url.username()); + *password = UnescapeIdentityString(url.password()); } bool HasGoogleHost(const GURL& url) { + return IsGoogleHost(url.host_piece()); +} + +bool IsGoogleHost(base::StringPiece host) { static const char* kGoogleHostSuffixes[] = { ".google.com", ".youtube.com", @@ -406,7 +425,6 @@ bool HasGoogleHost(const GURL& url) { ".googleapis.com", ".ytimg.com", }; - base::StringPiece host = url.host_piece(); for (const char* suffix : kGoogleHostSuffixes) { // Here it's possible to get away with faster case-sensitive comparisons // because the list above is all lowercase, and a GURL's host name will diff --git a/chromium/net/base/url_util.h b/chromium/net/base/url_util.h index c21c96e83b9..74d9746f7e8 100644 --- a/chromium/net/base/url_util.h +++ b/chromium/net/base/url_util.h @@ -172,6 +172,10 @@ NET_EXPORT_PRIVATE void GetIdentityFromURL(const GURL& url, // for histograms and shouldn't be used to affect behavior. NET_EXPORT_PRIVATE bool HasGoogleHost(const GURL& url); +// Returns true if |host| is the hostname of a Google server. This should only +// be used for histograms and shouldn't be used to affect behavior. +NET_EXPORT_PRIVATE bool IsGoogleHost(base::StringPiece host); + // This function tests |host| to see if its one used in the initial TLS 1.3 // deployment. TLS connections to them form the basis of our comparisons. NET_EXPORT_PRIVATE bool IsTLS13ExperimentHost(base::StringPiece host); diff --git a/chromium/net/base/url_util_unittest.cc b/chromium/net/base/url_util_unittest.cc index f57d89efb31..5785c7058aa 100644 --- a/chromium/net/base/url_util_unittest.cc +++ b/chromium/net/base/url_util_unittest.cc @@ -500,41 +500,76 @@ TEST(UrlUtilTest, GetIdentityFromURL) { const char* const expected_username; const char* const expected_password; } tests[] = { - { - "http://username:password@google.com", - "username", - "password", - }, - { // Test for http://crbug.com/19200 - "http://username:p@ssword@google.com", - "username", - "p@ssword", - }, - { // Special URL characters should be unescaped. - "http://username:p%3fa%26s%2fs%23@google.com", - "username", - "p?a&s/s#", - }, - { // Username contains %20. - "http://use rname:password@google.com", - "use rname", - "password", - }, - { // Keep %00 as is. - "http://use%00rname:password@google.com", - "use%00rname", - "password", - }, - { // Use a '+' in the username. - "http://use+rname:password@google.com", - "use+rname", - "password", - }, - { // Use a '&' in the password. - "http://username:p&ssword@google.com", - "username", - "p&ssword", - }, + { + "http://username:password@google.com", + "username", + "password", + }, + { + // Test for http://crbug.com/19200 + "http://username:p@ssword@google.com", + "username", + "p@ssword", + }, + { + // Special URL characters should be unescaped. + "http://username:p%3fa%26s%2fs%23@google.com", + "username", + "p?a&s/s#", + }, + { + // Username contains %20, password %25. + "http://use rname:password%25@google.com", + "use rname", + "password%", + }, + { + // Username and password contain forward / backward slashes. + "http://username%2F:password%5C@google.com", + "username/", + "password\\", + }, + { + // Keep %00 and %01 as-is, and ignore other escaped characters when + // present. + "http://use%00rname%20:pass%01word%25@google.com", + "use%00rname%20", + "pass%01word%25", + }, + { + // Keep CR and LF as-is. + "http://use%0Arname:pass%0Dword@google.com", + "use%0Arname", + "pass%0Dword", + }, + { + // Use a '+' in the username. + "http://use+rname:password@google.com", + "use+rname", + "password", + }, + { + // Use a '&' in the password. + "http://username:p&ssword@google.com", + "username", + "p&ssword", + }, + { + // These UTF-8 characters are considered unsafe to unescape by + // UnescapeURLComponent, but raise no special concerns as part of the + // identity portion of a URL. + "http://%F0%9F%94%92:%E2%80%82@google.com", + "\xF0\x9F\x94\x92", + "\xE2\x80\x82", + }, + { + // Leave invalid UTF-8 alone, and leave valid UTF-8 characters alone + // if there's also an invalid character in the string - strings should + // not be partially unescaped. + "http://%81:%E2%80%82%E2%80@google.com", + "%81", + "%E2%80%82%E2%80", + }, }; for (const auto& test : tests) { SCOPED_TRACE(test.input_url); @@ -543,8 +578,8 @@ TEST(UrlUtilTest, GetIdentityFromURL) { base::string16 username, password; GetIdentityFromURL(url, &username, &password); - EXPECT_EQ(ASCIIToUTF16(test.expected_username), username); - EXPECT_EQ(ASCIIToUTF16(test.expected_password), password); + EXPECT_EQ(base::UTF8ToUTF16(test.expected_username), username); + EXPECT_EQ(base::UTF8ToUTF16(test.expected_password), password); } } |