summaryrefslogtreecommitdiff
path: root/chromium/url
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-07-31 15:50:41 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-08-30 12:35:23 +0000
commit7b2ffa587235a47d4094787d72f38102089f402a (patch)
tree30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/url
parentd94af01c90575348c4e81a418257f254b6f8d225 (diff)
downloadqtwebengine-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.cc269
-rw-r--r--chromium/url/url_util.h20
-rw-r--r--chromium/url/url_util_unittest.cc12
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) {