diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-31 15:50:41 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:35:23 +0000 |
commit | 7b2ffa587235a47d4094787d72f38102089f402a (patch) | |
tree | 30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/url | |
parent | d94af01c90575348c4e81a418257f254b6f8d225 (diff) | |
download | qtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz |
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/url')
-rw-r--r-- | chromium/url/url_util.cc | 269 | ||||
-rw-r--r-- | chromium/url/url_util.h | 20 | ||||
-rw-r--r-- | chromium/url/url_util_unittest.cc | 12 |
3 files changed, 118 insertions, 183 deletions
diff --git a/chromium/url/url_util.cc b/chromium/url/url_util.cc index d56d0410457..63613aae47b 100644 --- a/chromium/url/url_util.cc +++ b/chromium/url/url_util.cc @@ -9,6 +9,7 @@ #include "base/debug/leak_annotations.h" #include "base/logging.h" +#include "base/no_destructor.h" #include "base/stl_util.h" #include "base/strings/string_util.h" #include "url/url_canon_internal.h" @@ -20,7 +21,82 @@ namespace url { namespace { -bool g_allow_non_standard_schemes = false; +// List of currently registered schemes and associated properties. +struct SchemeRegistry { + // Standard format schemes (see header for details). + std::vector<SchemeWithType> standard_schemes = { + {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + // Yes, file URLs can have a hostname, so file URLs should be handled as + // "standard". File URLs never have a port as specified by the SchemeType + // field. Unlike other SCHEME_WITH_HOST schemes, the 'host' in a file + // URL may be empty, a behavior which is special-cased during + // canonicalization. + {kFileScheme, SCHEME_WITH_HOST}, + {kFtpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + {kGopherScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + {kWssScheme, + SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket secure. + {kWsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket. + {kFileSystemScheme, SCHEME_WITHOUT_AUTHORITY}, + }; + + // Schemes that are allowed for referrers. + std::vector<SchemeWithType> referrer_schemes = { + {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + }; + + // Schemes that do not trigger mixed content warning. + std::vector<std::string> secure_schemes = { + kHttpsScheme, + kAboutScheme, + kDataScheme, + kWssScheme, + }; + + // Schemes that normal pages cannot link to or access (i.e., with the same + // security rules as those applied to "file" URLs). + std::vector<std::string> local_schemes = { + kFileScheme, + }; + + // Schemes that cause pages loaded with them to not have access to pages + // loaded with any other URL scheme. + std::vector<std::string> no_access_schemes = { + kAboutScheme, + kJavaScriptScheme, + kDataScheme, + }; + + // Schemes that can be sent CORS requests. + std::vector<std::string> cors_enabled_schemes = { + kHttpsScheme, + kHttpScheme, + kDataScheme, + }; + + // Schemes that can be used by web to store data (local storage, etc). + std::vector<std::string> web_storage_schemes = { + kHttpsScheme, kHttpScheme, kFileScheme, kFtpScheme, kWssScheme, kWsScheme, + }; + + // Schemes that can bypass the Content-Security-Policy (CSP) checks. + std::vector<std::string> csp_bypassing_schemes = {}; + + // Schemes that are strictly empty documents, allowing them to commit + // synchronously. + std::vector<std::string> empty_document_schemes = { + kAboutScheme, + }; + + bool allow_non_standard_schemes = false; +}; + +SchemeRegistry* GetSchemeRegistry() { + static base::NoDestructor<SchemeRegistry> registry; + return registry.get(); +} // Pass this enum through for methods which would like to know if whitespace // removal is necessary. @@ -29,79 +105,6 @@ enum WhitespaceRemovalPolicy { DO_NOT_REMOVE_WHITESPACE, }; -const SchemeWithType kStandardURLSchemes[] = { - {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - // Yes, file URLs can have a hostname, so file URLs should be handled as - // "standard". File URLs never have a port as specified by the SchemeType - // field. Unlike other SCHEME_WITH_HOST schemes, the 'host' in a file - // URL may be empty, a behavior which is special-cased during - // canonicalization. - {kFileScheme, SCHEME_WITH_HOST}, - {kFtpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - {kGopherScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - {kWssScheme, - SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket secure. - {kWsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // WebSocket. - {kFileSystemScheme, SCHEME_WITHOUT_AUTHORITY}, -}; - -const SchemeWithType kReferrerURLSchemes[] = { - {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, -}; - -const char* kSecureSchemes[] = { - kHttpsScheme, - kAboutScheme, - kDataScheme, - kWssScheme, -}; - -const char* kLocalSchemes[] = { - kFileScheme, -}; - -const char* kNoAccessSchemes[] = { - kAboutScheme, - kJavaScriptScheme, - kDataScheme, -}; - -const char* kCorsEnabledSchemes[] = { - kHttpsScheme, kHttpScheme, kDataScheme, -}; - -const char* kWebStorageSchemes[] = { - kHttpsScheme, - kHttpScheme, - kFileScheme, - kFtpScheme, - kWssScheme, - kWsScheme, -}; - -const char* kEmptyDocumentSchemes[] = { - kAboutScheme, -}; - -bool initialized = false; - -// Lists of the currently installed standard and referrer schemes. These lists -// are lazily initialized by Initialize and are leaked on shutdown to prevent -// any destructors from being called that will slow us down or cause problems. -std::vector<SchemeWithType>* standard_schemes = nullptr; -std::vector<SchemeWithType>* referrer_schemes = nullptr; - -// Similar to above, initialized by the Init*Schemes methods. -std::vector<std::string>* secure_schemes = nullptr; -std::vector<std::string>* local_schemes = nullptr; -std::vector<std::string>* no_access_schemes = nullptr; -std::vector<std::string>* cors_enabled_schemes = nullptr; -std::vector<std::string>* web_storage_schemes = nullptr; -std::vector<std::string>* csp_bypassing_schemes = nullptr; -std::vector<std::string>* empty_document_schemes = nullptr; - // See the LockSchemeRegistries declaration in the header. bool scheme_registries_locked = false; @@ -116,24 +119,6 @@ template<> struct CharToStringPiece<base::char16> { typedef base::StringPiece16 Piece; }; -void InitSchemes(std::vector<std::string>** schemes, - const char** initial_schemes, - size_t size) { - *schemes = new std::vector<std::string>(size); - for (size_t i = 0; i < size; i++) { - (*(*schemes))[i] = initial_schemes[i]; - } -} - -void InitSchemesWithType(std::vector<SchemeWithType>** schemes, - const SchemeWithType* initial_schemes, - size_t size) { - *schemes = new std::vector<SchemeWithType>(size); - for (size_t i = 0; i < size; i++) { - (*(*schemes))[i] = initial_schemes[i]; - } -} - // Given a string and a range inside the string, compares it to the given // lower-case |compare_to| buffer. template<typename CHAR> @@ -171,8 +156,8 @@ bool DoIsInSchemes(const CHAR* spec, template<typename CHAR> bool DoIsStandard(const CHAR* spec, const Component& scheme, SchemeType* type) { - Initialize(); - return DoIsInSchemes(spec, scheme, type, *standard_schemes); + return DoIsInSchemes(spec, scheme, type, + GetSchemeRegistry()->standard_schemes); } @@ -510,135 +495,83 @@ void DoAddSchemeWithType(const char* new_scheme, } // namespace void Initialize() { - if (initialized) - return; - InitSchemesWithType(&standard_schemes, kStandardURLSchemes, - base::size(kStandardURLSchemes)); - InitSchemesWithType(&referrer_schemes, kReferrerURLSchemes, - base::size(kReferrerURLSchemes)); - InitSchemes(&secure_schemes, kSecureSchemes, base::size(kSecureSchemes)); - InitSchemes(&local_schemes, kLocalSchemes, base::size(kLocalSchemes)); - InitSchemes(&no_access_schemes, kNoAccessSchemes, - base::size(kNoAccessSchemes)); - InitSchemes(&cors_enabled_schemes, kCorsEnabledSchemes, - base::size(kCorsEnabledSchemes)); - InitSchemes(&web_storage_schemes, kWebStorageSchemes, - base::size(kWebStorageSchemes)); - InitSchemes(&csp_bypassing_schemes, nullptr, 0); - InitSchemes(&empty_document_schemes, kEmptyDocumentSchemes, - base::size(kEmptyDocumentSchemes)); - initialized = true; + // Deprecated. } void Shutdown() { - initialized = false; - g_allow_non_standard_schemes = false; - delete standard_schemes; - standard_schemes = nullptr; - delete referrer_schemes; - referrer_schemes = nullptr; - delete secure_schemes; - secure_schemes = nullptr; - delete local_schemes; - local_schemes = nullptr; - delete no_access_schemes; - no_access_schemes = nullptr; - delete cors_enabled_schemes; - cors_enabled_schemes = nullptr; - delete web_storage_schemes; - web_storage_schemes = nullptr; - delete csp_bypassing_schemes; - csp_bypassing_schemes = nullptr; - delete empty_document_schemes; - empty_document_schemes = nullptr; + *GetSchemeRegistry() = SchemeRegistry(); } void EnableNonStandardSchemesForAndroidWebView() { - g_allow_non_standard_schemes = true; + GetSchemeRegistry()->allow_non_standard_schemes = true; } bool AllowNonStandardSchemesForAndroidWebView() { - return g_allow_non_standard_schemes; + return GetSchemeRegistry()->allow_non_standard_schemes; } void AddStandardScheme(const char* new_scheme, SchemeType type) { - Initialize(); - DoAddSchemeWithType(new_scheme, type, standard_schemes); + DoAddSchemeWithType(new_scheme, type, &GetSchemeRegistry()->standard_schemes); } void AddReferrerScheme(const char* new_scheme, SchemeType type) { - Initialize(); - DoAddSchemeWithType(new_scheme, type, referrer_schemes); + DoAddSchemeWithType(new_scheme, type, &GetSchemeRegistry()->referrer_schemes); } void AddSecureScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, secure_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->secure_schemes); } const std::vector<std::string>& GetSecureSchemes() { - Initialize(); - return *secure_schemes; + return GetSchemeRegistry()->secure_schemes; } void AddLocalScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, local_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->local_schemes); } const std::vector<std::string>& GetLocalSchemes() { - Initialize(); - return *local_schemes; + return GetSchemeRegistry()->local_schemes; } void AddNoAccessScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, no_access_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->no_access_schemes); } const std::vector<std::string>& GetNoAccessSchemes() { - Initialize(); - return *no_access_schemes; + return GetSchemeRegistry()->no_access_schemes; } void AddCorsEnabledScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, cors_enabled_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->cors_enabled_schemes); } const std::vector<std::string>& GetCorsEnabledSchemes() { - Initialize(); - return *cors_enabled_schemes; + return GetSchemeRegistry()->cors_enabled_schemes; } void AddWebStorageScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, web_storage_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->web_storage_schemes); } const std::vector<std::string>& GetWebStorageSchemes() { - Initialize(); - return *web_storage_schemes; + return GetSchemeRegistry()->web_storage_schemes; } void AddCSPBypassingScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, csp_bypassing_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->csp_bypassing_schemes); } const std::vector<std::string>& GetCSPBypassingSchemes() { - Initialize(); - return *csp_bypassing_schemes; + return GetSchemeRegistry()->csp_bypassing_schemes; } void AddEmptyDocumentScheme(const char* new_scheme) { - Initialize(); - DoAddScheme(new_scheme, empty_document_schemes); + DoAddScheme(new_scheme, &GetSchemeRegistry()->empty_document_schemes); } const std::vector<std::string>& GetEmptyDocumentSchemes() { - Initialize(); - return *empty_document_schemes; + return GetSchemeRegistry()->empty_document_schemes; } void LockSchemeRegistries() { @@ -668,9 +601,9 @@ bool IsStandard(const base::char16* spec, const Component& scheme) { } bool IsReferrerScheme(const char* spec, const Component& scheme) { - Initialize(); SchemeType unused_scheme_type; - return DoIsInSchemes(spec, scheme, &unused_scheme_type, *referrer_schemes); + return DoIsInSchemes(spec, scheme, &unused_scheme_type, + GetSchemeRegistry()->referrer_schemes); } bool FindAndCompareScheme(const char* str, diff --git a/chromium/url/url_util.h b/chromium/url/url_util.h index 0bd9f40718d..b618999d9d0 100644 --- a/chromium/url/url_util.h +++ b/chromium/url/url_util.h @@ -19,22 +19,10 @@ namespace url { // Init ------------------------------------------------------------------------ -// Initialization is NOT required, it will be implicitly initialized when first -// used. However, this implicit initialization is NOT threadsafe. If you are -// using this library in a threaded environment and don't have a consistent -// "first call" (an example might be calling Add*Scheme with your special -// application-specific schemes) then you will want to call initialize before -// spawning any threads. -// -// It is OK to call this function more than once, subsequent calls will be -// no-ops, unless Shutdown was called in the mean time. This will also be a -// no-op if other calls to the library have forced an initialization beforehand. +// Deprecated. Does not do anything. COMPONENT_EXPORT(URL) void Initialize(); -// Cleanup is not required, except some strings may leak. For most user -// applications, this is fine. If you're using it in a library that may get -// loaded and unloaded, you'll want to unload to properly clean up your -// library. +// Resets all custom schemes to the default values. Not thread-safe. COMPONENT_EXPORT(URL) void Shutdown(); // Schemes --------------------------------------------------------------------- @@ -45,6 +33,8 @@ COMPONENT_EXPORT(URL) void Shutdown(); // compatibility, which allows the use of custom schemes: content hosted in // Android WebView assumes that one URL with a non-standard scheme will be // same-origin to another URL with the same non-standard scheme. +// +// Not thread-safe. COMPONENT_EXPORT(URL) void EnableNonStandardSchemesForAndroidWebView(); // Whether or not SchemeHostPort and Origin allow non-standard schemes. @@ -103,7 +93,7 @@ COMPONENT_EXPORT(URL) void AddWebStorageScheme(const char* new_scheme); COMPONENT_EXPORT(URL) const std::vector<std::string>& GetWebStorageSchemes(); // Adds an application-defined scheme to the list of schemes that can bypass the -// Content-Security-Policy(CSP) checks. +// Content-Security-Policy (CSP) checks. COMPONENT_EXPORT(URL) void AddCSPBypassingScheme(const char* new_scheme); COMPONENT_EXPORT(URL) const std::vector<std::string>& GetCSPBypassingSchemes(); diff --git a/chromium/url/url_util_unittest.cc b/chromium/url/url_util_unittest.cc index 13036af8498..da578e81540 100644 --- a/chromium/url/url_util_unittest.cc +++ b/chromium/url/url_util_unittest.cc @@ -94,8 +94,20 @@ TEST_F(URLUtilTest, IsReferrerScheme) { TEST_F(URLUtilTest, AddReferrerScheme) { const char kFooScheme[] = "foo"; EXPECT_FALSE(IsReferrerScheme(kFooScheme, Component(0, strlen(kFooScheme)))); + + AddReferrerScheme(kFooScheme, url::SCHEME_WITH_HOST); + EXPECT_TRUE(IsReferrerScheme(kFooScheme, Component(0, strlen(kFooScheme)))); +} + +TEST_F(URLUtilTest, ShutdownCleansUpSchemes) { + const char kFooScheme[] = "foo"; + EXPECT_FALSE(IsReferrerScheme(kFooScheme, Component(0, strlen(kFooScheme)))); + AddReferrerScheme(kFooScheme, url::SCHEME_WITH_HOST); EXPECT_TRUE(IsReferrerScheme(kFooScheme, Component(0, strlen(kFooScheme)))); + + Shutdown(); + EXPECT_FALSE(IsReferrerScheme(kFooScheme, Component(0, strlen(kFooScheme)))); } TEST_F(URLUtilTest, GetStandardSchemeType) { |