Index: chrome/common/extensions/extension.cc |
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc |
index 32c4efb894e172c907542b4913914b253084066a..8b69f805b165c210d4f264937e94aebcd2afcb9f 100644 |
--- a/chrome/common/extensions/extension.cc |
+++ b/chrome/common/extensions/extension.cc |
@@ -217,8 +217,11 @@ const char Extension::kMimeType[] = "application/x-chrome-extension"; |
const int Extension::kValidWebExtentSchemes = |
URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; |
-const int Extension::kValidHostPermissionSchemes = |
- UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; |
+const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI | |
+ URLPattern::SCHEME_HTTP | |
+ URLPattern::SCHEME_HTTPS | |
+ URLPattern::SCHEME_FILE | |
+ URLPattern::SCHEME_FTP; |
Extension::Requirements::Requirements() |
: webgl(false), |
@@ -590,26 +593,50 @@ bool Extension::ParsePermissions(const char* key, |
URLPattern pattern = URLPattern(kAllowedSchemes); |
URLPattern::ParseResult parse_result = pattern.Parse(permission_str); |
if (parse_result == URLPattern::PARSE_SUCCESS) { |
- if (!CanSpecifyHostPermission(pattern, *api_permissions)) { |
- *error = ErrorUtils::FormatErrorMessageUTF16( |
- errors::kInvalidPermissionScheme, permission_str); |
- return false; |
- } |
- |
// The path component is not used for host permissions, so we force it |
// to match all paths. |
pattern.SetPath("/*"); |
- |
+ int valid_schemes = pattern.valid_schemes(); |
if (pattern.MatchesScheme(chrome::kFileScheme) && |
!CanExecuteScriptEverywhere()) { |
wants_file_access_ = true; |
- if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { |
- pattern.SetValidSchemes( |
- pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); |
- } |
+ if (!(creation_flags_ & ALLOW_FILE_ACCESS)) |
+ valid_schemes &= ~URLPattern::SCHEME_FILE; |
+ } |
+ |
+ if (pattern.scheme() != chrome::kChromeUIScheme && |
+ !CanExecuteScriptEverywhere()) { |
+ // Keep chrome:// in allowed schemes only if it's explicitly requested |
+ // or CanExecuteScriptEverywhere is true. If the |
+ // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission |
+ // will fail, so don't check the flag here. |
+ valid_schemes &= ~URLPattern::SCHEME_CHROMEUI; |
+ } |
+ pattern.SetValidSchemes(valid_schemes); |
+ |
+ if (!CanSpecifyHostPermission(pattern, *api_permissions)) { |
+ // TODO(aboxhall): make a warning (see line 633) |
+ *error = ErrorUtils::FormatErrorMessageUTF16( |
+ errors::kInvalidPermissionScheme, permission_str); |
+ return false; |
} |
host_permissions->AddPattern(pattern); |
+ |
+ // We need to make sure all_urls matches chrome://favicon and |
+ // (maybe) chrome://thumbnail, so add them back in to host_permissions |
+ // separately. |
+ if (pattern.match_all_urls()) { |
+ host_permissions->AddPattern( |
+ URLPattern(URLPattern::SCHEME_CHROMEUI, |
+ chrome::kChromeUIFaviconURL)); |
+ if (api_permissions->find(APIPermission::kExperimental) != |
+ api_permissions->end()) { |
+ host_permissions->AddPattern( |
+ URLPattern(URLPattern::SCHEME_CHROMEUI, |
+ chrome::kChromeUIThumbnailURL)); |
+ } |
+ } |
continue; |
} |
@@ -664,13 +691,6 @@ bool Extension::CanSilentlyIncreasePermissions() const { |
} |
bool Extension::HasHostPermission(const GURL& url) const { |
- if (url.SchemeIs(chrome::kChromeUIScheme) && |
- url.host() != chrome::kChromeUIFaviconHost && |
- url.host() != chrome::kChromeUIThumbnailHost && |
- location() != Manifest::COMPONENT) { |
- return false; |
- } |
- |
base::AutoLock auto_lock(runtime_data_lock_); |
return runtime_data_.GetActivePermissions()-> |
HasExplicitAccessToOrigin(url); |
@@ -803,9 +823,12 @@ bool Extension::CanExecuteScriptOnPage(const GURL& document_url, |
return false; |
} |
- if (document_url.SchemeIs(chrome::kChromeUIScheme) && |
- !CanExecuteScriptEverywhere()) { |
- return false; |
+ if (!CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kExtensionsOnChromeURLs)) { |
+ if (document_url.SchemeIs(chrome::kChromeUIScheme) && |
+ !CanExecuteScriptEverywhere()) { |
+ return false; |
+ } |
} |
if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && |
@@ -1962,6 +1985,7 @@ bool Extension::LoadExtensionFeatures(string16* error) { |
bool Extension::LoadContentScripts(string16* error) { |
if (!manifest_->HasKey(keys::kContentScripts)) |
return true; |
+ |
const ListValue* list_value; |
if (!manifest_->GetList(keys::kContentScripts, &list_value)) { |
*error = ASCIIToUTF16(errors::kInvalidContentScriptsList); |
@@ -1979,6 +2003,7 @@ bool Extension::LoadContentScripts(string16* error) { |
UserScript script; |
if (!LoadUserScriptHelper(content_script, i, error, &script)) |
return false; // Failed to parse script context definition. |
+ |
script.set_extension_id(id()); |
if (converted_from_user_script_) { |
script.set_emulate_greasemonkey(true); |
@@ -2104,9 +2129,8 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, |
return false; |
} |
- URLPattern pattern(UserScript::kValidUserScriptSchemes); |
- if (CanExecuteScriptEverywhere()) |
- pattern.SetValidSchemes(URLPattern::SCHEME_ALL); |
+ URLPattern pattern( |
+ UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere())); |
URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
if (parse_result != URLPattern::PARSE_SUCCESS) { |
@@ -2118,6 +2142,17 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, |
return false; |
} |
+ // TODO(aboxhall): check for webstore |
+ if (!CanExecuteScriptEverywhere() && |
+ pattern.scheme() != chrome::kChromeUIScheme) { |
+ // Exclude SCHEME_CHROMEUI unless it's been explicitly requested. |
+ // If the --extensions-on-chrome-urls flag has not been passed, requesting |
+ // a chrome:// url will cause a parse failure above, so there's no need to |
+ // check the flag here. |
+ pattern.SetValidSchemes( |
+ pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI); |
+ } |
+ |
if (pattern.MatchesScheme(chrome::kFileScheme) && |
!CanExecuteScriptEverywhere()) { |
wants_file_access_ = true; |
@@ -2151,9 +2186,9 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, |
return false; |
} |
- URLPattern pattern(UserScript::kValidUserScriptSchemes); |
- if (CanExecuteScriptEverywhere()) |
- pattern.SetValidSchemes(URLPattern::SCHEME_ALL); |
+ int valid_schemes = |
+ UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere()); |
+ URLPattern pattern(valid_schemes); |
URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
if (parse_result != URLPattern::PARSE_SUCCESS) { |
*error = ErrorUtils::FormatErrorMessageUTF16( |
@@ -2357,6 +2392,12 @@ bool Extension::CanSpecifyHostPermission(const URLPattern& pattern, |
if (CanExecuteScriptEverywhere()) |
return true; |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kExtensionsOnChromeURLs)) |
+ return true; |
+ |
+ // TODO(aboxhall): return from_webstore() when webstore handles blocking |
+ // extensions which request chrome:// urls |
return false; |
} |