Index: url/url_util.cc |
diff --git a/url/url_util.cc b/url/url_util.cc |
index b3e360424152668e0a786883ad206734fc657366..484e2298c6133c906f2772476e0a0d482721da65 100644 |
--- a/url/url_util.cc |
+++ b/url/url_util.cc |
@@ -6,12 +6,12 @@ |
#include <stddef.h> |
#include <string.h> |
-#include <vector> |
#include "base/debug/leak_annotations.h" |
#include "base/logging.h" |
#include "base/strings/string_util.h" |
#include "url/url_canon_internal.h" |
+#include "url/url_constants.h" |
#include "url/url_file.h" |
#include "url/url_util_internal.h" |
@@ -26,8 +26,7 @@ enum WhitespaceRemovalPolicy { |
DO_NOT_REMOVE_WHITESPACE, |
}; |
-const int kNumStandardURLSchemes = 10; |
-const SchemeWithType kStandardURLSchemes[kNumStandardURLSchemes] = { |
+const SchemeWithType kStandardURLSchemes[] = { |
{kHttpScheme, SCHEME_WITH_PORT}, |
{kHttpsScheme, SCHEME_WITH_PORT}, |
// Yes, file URLs can have a hostname, so file URLs should be handled as |
@@ -43,21 +42,50 @@ const SchemeWithType kStandardURLSchemes[kNumStandardURLSchemes] = { |
{kHttpsSuboriginScheme, SCHEME_WITH_PORT}, |
}; |
-const int kNumReferrerURLSchemes = 4; |
-const SchemeWithType kReferrerURLSchemes[kNumReferrerURLSchemes] = { |
+const SchemeWithType kReferrerURLSchemes[] = { |
{kHttpScheme, SCHEME_WITH_PORT}, |
{kHttpsScheme, SCHEME_WITH_PORT}, |
{kHttpSuboriginScheme, SCHEME_WITH_PORT}, |
{kHttpsSuboriginScheme, SCHEME_WITH_PORT}, |
}; |
+const char* kSecureSchemes[] = { |
+ kHttpsScheme, |
+ kAboutScheme, |
+ kDataScheme, |
+ kWssScheme, |
+}; |
+ |
+const char* kLocalSchemes[] = { |
+ kFileScheme, |
+}; |
+ |
+const char* kNoAccessSchemes[] = { |
+ kAboutScheme, |
+ kJavaScriptScheme, |
+ kDataScheme, |
+}; |
+ |
+const char* kCORSEnabledSchemes[] = { |
+ kHttpScheme, |
+ kHttpsScheme, |
+ kDataScheme, |
+}; |
+ |
+bool initialized = false; |
+ |
// Lists of the currently installed standard and referrer schemes. These lists |
-// are lazily initialized by InitStandardSchemes and InitReferrerSchemes and are |
-// leaked on shutdown to prevent any destructors from being called that will |
-// slow us down or cause problems. |
+// 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; |
+ |
// See the LockSchemeRegistries declaration in the header. |
bool scheme_registries_locked = false; |
@@ -72,27 +100,22 @@ template<> struct CharToStringPiece<base::char16> { |
typedef base::StringPiece16 Piece; |
}; |
-void InitSchemes(std::vector<SchemeWithType>** schemes, |
- const SchemeWithType* initial_schemes, |
+void InitSchemes(std::vector<std::string>** schemes, |
+ const char** initial_schemes, |
size_t size) { |
- if (*schemes) |
- return; |
- *schemes = new std::vector<SchemeWithType>(size); |
+ *schemes = new std::vector<std::string>(size); |
for (size_t i = 0; i < size; i++) { |
- (*schemes)->push_back(initial_schemes[i]); |
+ (*(*schemes))[i] = initial_schemes[i]; |
} |
} |
-// Ensures that the standard_schemes list is initialized, does nothing if |
-// it already has values. |
-void InitStandardSchemes() { |
- InitSchemes(&standard_schemes, kStandardURLSchemes, kNumStandardURLSchemes); |
-} |
- |
-// Ensures that the referrer_schemes list is initialized, does nothing if |
-// it already has values. |
-void InitReferrerSchemes() { |
- InitSchemes(&referrer_schemes, kReferrerURLSchemes, kNumReferrerURLSchemes); |
+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 |
@@ -132,7 +155,7 @@ bool DoIsInSchemes(const CHAR* spec, |
template<typename CHAR> |
bool DoIsStandard(const CHAR* spec, const Component& scheme, SchemeType* type) { |
- InitStandardSchemes(); |
+ Initialize(); |
return DoIsInSchemes(spec, scheme, type, *standard_schemes); |
} |
@@ -403,9 +426,7 @@ bool DoReplaceComponents(const char* spec, |
return ReplacePathURL(spec, parsed, replacements, output, out_parsed); |
} |
-void DoAddScheme(const char* new_scheme, |
- SchemeType type, |
- std::vector<SchemeWithType>* schemes) { |
+void DoAddScheme(const char* new_scheme, std::vector<std::string>* schemes) { |
DCHECK(schemes); |
// If this assert triggers, it means you've called Add*Scheme after |
// LockSchemeRegistries has been called (see the header file for |
@@ -421,6 +442,29 @@ void DoAddScheme(const char* new_scheme, |
if (scheme_len == 0) |
return; |
+ DCHECK_EQ(base::ToLowerASCII(new_scheme), new_scheme); |
+ schemes->push_back(std::string(new_scheme)); |
+} |
+ |
+void DoAddSchemeWithType(const char* new_scheme, |
+ SchemeType type, |
+ std::vector<SchemeWithType>* schemes) { |
+ DCHECK(schemes); |
+ // If this assert triggers, it means you've called Add*Scheme after |
+ // LockSchemeRegistries has been called (see the header file for |
+ // LockSchemeRegistries for more). |
+ // |
+ // This normally means you're trying to set up a new scheme too late in your |
+ // application's init process. Locate where your app does this initialization |
+ // and calls LockSchemeRegistries, and add your new scheme there. |
+ DCHECK(!scheme_registries_locked) |
+ << "Trying to add a scheme after the lists have been locked."; |
+ |
+ size_t scheme_len = strlen(new_scheme); |
+ if (scheme_len == 0) |
+ return; |
+ |
+ DCHECK_EQ(base::ToLowerASCII(new_scheme), new_scheme); |
// Duplicate the scheme into a new buffer and add it to the list of standard |
// schemes. This pointer will be leaked on shutdown. |
char* dup_scheme = new char[scheme_len + 1]; |
@@ -436,29 +480,85 @@ void DoAddScheme(const char* new_scheme, |
} // namespace |
void Initialize() { |
- InitStandardSchemes(); |
- InitReferrerSchemes(); |
+ if (initialized) |
+ return; |
+ InitSchemesWithType(&standard_schemes, kStandardURLSchemes, |
+ arraysize(kStandardURLSchemes)); |
+ InitSchemesWithType(&referrer_schemes, kReferrerURLSchemes, |
+ arraysize(kReferrerURLSchemes)); |
+ InitSchemes(&secure_schemes, kSecureSchemes, arraysize(kSecureSchemes)); |
+ InitSchemes(&local_schemes, kLocalSchemes, arraysize(kLocalSchemes)); |
+ InitSchemes(&no_access_schemes, kNoAccessSchemes, |
+ arraysize(kNoAccessSchemes)); |
+ InitSchemes(&cors_enabled_schemes, kCORSEnabledSchemes, |
+ arraysize(kCORSEnabledSchemes)); |
+ initialized = true; |
} |
void Shutdown() { |
- if (standard_schemes) { |
- delete standard_schemes; |
- standard_schemes = NULL; |
- } |
- if (referrer_schemes) { |
- delete referrer_schemes; |
- referrer_schemes = NULL; |
- } |
+ initialized = 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; |
} |
void AddStandardScheme(const char* new_scheme, SchemeType type) { |
- InitStandardSchemes(); |
- DoAddScheme(new_scheme, type, standard_schemes); |
+ Initialize(); |
+ DoAddSchemeWithType(new_scheme, type, standard_schemes); |
} |
void AddReferrerScheme(const char* new_scheme, SchemeType type) { |
- InitReferrerSchemes(); |
- DoAddScheme(new_scheme, type, referrer_schemes); |
+ Initialize(); |
+ DoAddSchemeWithType(new_scheme, type, referrer_schemes); |
+} |
+ |
+void AddSecureScheme(const char* new_scheme) { |
+ Initialize(); |
+ DoAddScheme(new_scheme, secure_schemes); |
+} |
+ |
+const std::vector<std::string>& GetSecureSchemes() { |
+ Initialize(); |
+ return *secure_schemes; |
+} |
+ |
+void AddLocalScheme(const char* new_scheme) { |
+ Initialize(); |
+ DoAddScheme(new_scheme, local_schemes); |
+} |
+ |
+const std::vector<std::string>& GetLocalSchemes() { |
+ Initialize(); |
+ return *local_schemes; |
+} |
+ |
+void AddNoAccessScheme(const char* new_scheme) { |
+ Initialize(); |
+ DoAddScheme(new_scheme, no_access_schemes); |
+} |
+ |
+const std::vector<std::string>& GetNoAccessSchemes() { |
+ Initialize(); |
+ return *no_access_schemes; |
+} |
+ |
+void AddCORSEnabledScheme(const char* new_scheme) { |
+ Initialize(); |
+ DoAddScheme(new_scheme, cors_enabled_schemes); |
+} |
+ |
+const std::vector<std::string>& GetCORSEnabledSchemes() { |
+ Initialize(); |
+ return *cors_enabled_schemes; |
} |
void LockSchemeRegistries() { |
@@ -482,7 +582,7 @@ bool IsStandard(const base::char16* spec, const Component& scheme) { |
} |
bool IsReferrerScheme(const char* spec, const Component& scheme) { |
- InitReferrerSchemes(); |
+ Initialize(); |
SchemeType unused_scheme_type; |
return DoIsInSchemes(spec, scheme, &unused_scheme_type, *referrer_schemes); |
} |