OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/common/chrome_constants.h" | 25 #include "chrome/common/chrome_constants.h" |
26 #include "chrome/common/chrome_switches.h" | 26 #include "chrome/common/chrome_switches.h" |
27 #include "chrome/common/chrome_version_info.h" | 27 #include "chrome/common/chrome_version_info.h" |
28 #include "chrome/common/extensions/extension_action.h" | 28 #include "chrome/common/extensions/extension_action.h" |
29 #include "chrome/common/extensions/extension_constants.h" | 29 #include "chrome/common/extensions/extension_constants.h" |
30 #include "chrome/common/extensions/extension_error_utils.h" | 30 #include "chrome/common/extensions/extension_error_utils.h" |
31 #include "chrome/common/extensions/extension_l10n_util.h" | 31 #include "chrome/common/extensions/extension_l10n_util.h" |
32 #include "chrome/common/extensions/extension_resource.h" | 32 #include "chrome/common/extensions/extension_resource.h" |
33 #include "chrome/common/extensions/extension_sidebar_defaults.h" | 33 #include "chrome/common/extensions/extension_sidebar_defaults.h" |
34 #include "chrome/common/extensions/extension_sidebar_utils.h" | 34 #include "chrome/common/extensions/extension_sidebar_utils.h" |
| 35 #include "chrome/common/extensions/file_browser_action.h" |
35 #include "chrome/common/extensions/user_script.h" | 36 #include "chrome/common/extensions/user_script.h" |
36 #include "chrome/common/url_constants.h" | 37 #include "chrome/common/url_constants.h" |
37 #include "googleurl/src/url_util.h" | 38 #include "googleurl/src/url_util.h" |
38 #include "grit/chromium_strings.h" | 39 #include "grit/chromium_strings.h" |
39 #include "grit/generated_resources.h" | 40 #include "grit/generated_resources.h" |
40 #include "grit/theme_resources.h" | 41 #include "grit/theme_resources.h" |
41 #include "net/base/registry_controlled_domain.h" | 42 #include "net/base/registry_controlled_domain.h" |
42 #include "third_party/skia/include/core/SkBitmap.h" | 43 #include "third_party/skia/include/core/SkBitmap.h" |
43 #include "ui/base/l10n/l10n_util.h" | 44 #include "ui/base/l10n/l10n_util.h" |
44 #include "ui/base/resource/resource_bundle.h" | 45 #include "ui/base/resource/resource_bundle.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 | 204 |
204 // Explicit permissions -- permission declaration required. | 205 // Explicit permissions -- permission declaration required. |
205 const char Extension::kBackgroundPermission[] = "background"; | 206 const char Extension::kBackgroundPermission[] = "background"; |
206 const char Extension::kBookmarkPermission[] = "bookmarks"; | 207 const char Extension::kBookmarkPermission[] = "bookmarks"; |
207 const char Extension::kContextMenusPermission[] = "contextMenus"; | 208 const char Extension::kContextMenusPermission[] = "contextMenus"; |
208 const char Extension::kContentSettingsPermission[] = "contentSettings"; | 209 const char Extension::kContentSettingsPermission[] = "contentSettings"; |
209 const char Extension::kCookiePermission[] = "cookies"; | 210 const char Extension::kCookiePermission[] = "cookies"; |
210 const char Extension::kChromeosInfoPrivatePermissions[] = "chromeosInfoPrivate"; | 211 const char Extension::kChromeosInfoPrivatePermissions[] = "chromeosInfoPrivate"; |
211 const char Extension::kDebuggerPermission[] = "debugger"; | 212 const char Extension::kDebuggerPermission[] = "debugger"; |
212 const char Extension::kExperimentalPermission[] = "experimental"; | 213 const char Extension::kExperimentalPermission[] = "experimental"; |
213 const char Extension::kFileSystemPermission[] = "fileSystem"; | 214 const char Extension::kFileBrowserHandlerPermission[] = "fileBrowserHandler"; |
214 const char Extension::kFileBrowserPrivatePermission[] = "fileBrowserPrivate"; | 215 const char Extension::kFileBrowserPrivatePermission[] = "fileBrowserPrivate"; |
215 const char Extension::kGeolocationPermission[] = "geolocation"; | 216 const char Extension::kGeolocationPermission[] = "geolocation"; |
216 const char Extension::kHistoryPermission[] = "history"; | 217 const char Extension::kHistoryPermission[] = "history"; |
217 const char Extension::kIdlePermission[] = "idle"; | 218 const char Extension::kIdlePermission[] = "idle"; |
218 const char Extension::kManagementPermission[] = "management"; | 219 const char Extension::kManagementPermission[] = "management"; |
219 const char Extension::kNotificationPermission[] = "notifications"; | 220 const char Extension::kNotificationPermission[] = "notifications"; |
220 const char Extension::kProxyPermission[] = "proxy"; | 221 const char Extension::kProxyPermission[] = "proxy"; |
221 const char Extension::kTabPermission[] = "tabs"; | 222 const char Extension::kTabPermission[] = "tabs"; |
222 const char Extension::kUnlimitedStoragePermission[] = "unlimitedStorage"; | 223 const char Extension::kUnlimitedStoragePermission[] = "unlimitedStorage"; |
223 const char Extension::kWebstorePrivatePermission[] = "webstorePrivate"; | 224 const char Extension::kWebstorePrivatePermission[] = "webstorePrivate"; |
224 | 225 |
225 // In general, all permissions should have an install message. | 226 // In general, all permissions should have an install message. |
226 // See ExtensionsTest.PermissionMessages for an explanation of each | 227 // See ExtensionsTest.PermissionMessages for an explanation of each |
227 // exception. | 228 // exception. |
228 const Extension::Permission Extension::kPermissions[] = { | 229 const Extension::Permission Extension::kPermissions[] = { |
229 { kBackgroundPermission, 0 }, | 230 { kBackgroundPermission, 0 }, |
230 { kBookmarkPermission, IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS }, | 231 { kBookmarkPermission, IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS }, |
231 { kChromeosInfoPrivatePermissions, 0}, | 232 { kChromeosInfoPrivatePermissions, 0}, |
232 { kContentSettingsPermission, 0 }, | 233 { kContentSettingsPermission, 0 }, |
233 { kContextMenusPermission, 0 }, | 234 { kContextMenusPermission, 0 }, |
234 { kCookiePermission, 0 }, | 235 { kCookiePermission, 0 }, |
235 { kDebuggerPermission, IDS_EXTENSION_PROMPT_WARNING_DEBUGGER }, | 236 { kDebuggerPermission, IDS_EXTENSION_PROMPT_WARNING_DEBUGGER }, |
236 { kExperimentalPermission, 0 }, | 237 { kExperimentalPermission, 0 }, |
237 { kFileSystemPermission, 0 }, | 238 { kFileBrowserHandlerPermission, 0 }, |
238 { kFileBrowserPrivatePermission, 0 }, | 239 { kFileBrowserPrivatePermission, 0 }, |
239 { kGeolocationPermission, IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION }, | 240 { kGeolocationPermission, IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION }, |
240 { kIdlePermission, 0 }, | 241 { kIdlePermission, 0 }, |
241 { kHistoryPermission, IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY }, | 242 { kHistoryPermission, IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY }, |
242 { kManagementPermission, IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT }, | 243 { kManagementPermission, IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT }, |
243 { kNotificationPermission, 0 }, | 244 { kNotificationPermission, 0 }, |
244 { kProxyPermission, 0 }, | 245 { kProxyPermission, 0 }, |
245 { kTabPermission, IDS_EXTENSION_PROMPT_WARNING_TABS }, | 246 { kTabPermission, IDS_EXTENSION_PROMPT_WARNING_TABS }, |
246 { kUnlimitedStoragePermission, 0 }, | 247 { kUnlimitedStoragePermission, 0 }, |
247 { kWebstorePrivatePermission, 0 }, | 248 { kWebstorePrivatePermission, 0 }, |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 result->SetPopupUrl(ExtensionAction::kDefaultTabId, url); | 873 result->SetPopupUrl(ExtensionAction::kDefaultTabId, url); |
873 } else { | 874 } else { |
874 DCHECK(!result->HasPopup(ExtensionAction::kDefaultTabId)) | 875 DCHECK(!result->HasPopup(ExtensionAction::kDefaultTabId)) |
875 << "Shouldn't be posible for the popup to be set."; | 876 << "Shouldn't be posible for the popup to be set."; |
876 } | 877 } |
877 } | 878 } |
878 | 879 |
879 return result.release(); | 880 return result.release(); |
880 } | 881 } |
881 | 882 |
| 883 Extension::FileBrowserActionList* Extension::LoadFileBrowserActions( |
| 884 const ListValue* extension_actions, std::string* error) { |
| 885 scoped_ptr<FileBrowserActionList> result( |
| 886 new FileBrowserActionList()); |
| 887 for (ListValue::const_iterator iter = extension_actions->begin(); |
| 888 iter != extension_actions->end(); |
| 889 ++iter) { |
| 890 if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) { |
| 891 *error = errors::kInvalidFileBrowserAction; |
| 892 return false; |
| 893 } |
| 894 scoped_ptr<FileBrowserAction> action( |
| 895 LoadFileBrowserAction( |
| 896 reinterpret_cast<DictionaryValue*>(*iter), error)); |
| 897 if (!action.get()) |
| 898 return NULL; // Failed to parse file browser action definition. |
| 899 result->push_back(linked_ptr<FileBrowserAction>(action.release())); |
| 900 } |
| 901 return result.release(); |
| 902 } |
| 903 |
| 904 FileBrowserAction* Extension::LoadFileBrowserAction( |
| 905 const DictionaryValue* file_browser_action, std::string* error) { |
| 906 scoped_ptr<FileBrowserAction> result( |
| 907 new FileBrowserAction()); |
| 908 result->set_extension_id(id()); |
| 909 |
| 910 std::string id; |
| 911 // Read the file action |id| (mandatory). |
| 912 if (!file_browser_action->HasKey(keys::kPageActionId) || |
| 913 !file_browser_action->GetString(keys::kPageActionId, &id)) { |
| 914 *error = errors::kInvalidPageActionId; |
| 915 return NULL; |
| 916 } |
| 917 result->set_id(id); |
| 918 |
| 919 // Read the page action title from |default_title| (mandatory). |
| 920 std::string title; |
| 921 if (!file_browser_action->HasKey(keys::kPageActionDefaultTitle) || |
| 922 !file_browser_action->GetString(keys::kPageActionDefaultTitle, &title)) { |
| 923 *error = errors::kInvalidPageActionDefaultTitle; |
| 924 return NULL; |
| 925 } |
| 926 result->set_title(title); |
| 927 |
| 928 // Initialize file filters (mandatory). |
| 929 ListValue* list_value = NULL; |
| 930 if (!file_browser_action->HasKey(keys::kFileFilters) || |
| 931 !file_browser_action->GetList(keys::kFileFilters, &list_value) || |
| 932 list_value->empty()) { |
| 933 *error = errors::kInvalidFileFiltersList; |
| 934 return false; |
| 935 } |
| 936 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 937 std::string filter; |
| 938 if (!list_value->GetString(i, &filter)) { |
| 939 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 940 errors::kInvalidFileFilterValue, base::IntToString(i)); |
| 941 return false; |
| 942 } |
| 943 URLPattern pattern(URLPattern::SCHEME_FILESYSTEM); |
| 944 if (URLPattern::PARSE_SUCCESS != pattern.Parse(filter, |
| 945 URLPattern::PARSE_STRICT)) { |
| 946 *error = ExtensionErrorUtils::FormatErrorMessage( |
| 947 errors::kInvalidURLPatternError, filter); |
| 948 return false; |
| 949 } |
| 950 result->AddPattern(pattern); |
| 951 } |
| 952 |
| 953 std::string default_icon; |
| 954 // Read the file browser action |default_icon| (optional). |
| 955 if (file_browser_action->HasKey(keys::kPageActionDefaultIcon)) { |
| 956 if (!file_browser_action->GetString( |
| 957 keys::kPageActionDefaultIcon,&default_icon) || |
| 958 default_icon.empty()) { |
| 959 *error = errors::kInvalidPageActionIconPath; |
| 960 return NULL; |
| 961 } |
| 962 result->set_icon_path(default_icon); |
| 963 } |
| 964 |
| 965 return result.release(); |
| 966 } |
| 967 |
882 ExtensionSidebarDefaults* Extension::LoadExtensionSidebarDefaults( | 968 ExtensionSidebarDefaults* Extension::LoadExtensionSidebarDefaults( |
883 const DictionaryValue* extension_sidebar, std::string* error) { | 969 const DictionaryValue* extension_sidebar, std::string* error) { |
884 scoped_ptr<ExtensionSidebarDefaults> result(new ExtensionSidebarDefaults()); | 970 scoped_ptr<ExtensionSidebarDefaults> result(new ExtensionSidebarDefaults()); |
885 | 971 |
886 std::string default_icon; | 972 std::string default_icon; |
887 // Read sidebar's |default_icon| (optional). | 973 // Read sidebar's |default_icon| (optional). |
888 if (extension_sidebar->HasKey(keys::kSidebarDefaultIcon)) { | 974 if (extension_sidebar->HasKey(keys::kSidebarDefaultIcon)) { |
889 if (!extension_sidebar->GetString(keys::kSidebarDefaultIcon, | 975 if (!extension_sidebar->GetString(keys::kSidebarDefaultIcon, |
890 &default_icon) || | 976 &default_icon) || |
891 default_icon.empty()) { | 977 default_icon.empty()) { |
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1903 *error = errors::kInvalidBrowserAction; | 1989 *error = errors::kInvalidBrowserAction; |
1904 return false; | 1990 return false; |
1905 } | 1991 } |
1906 | 1992 |
1907 browser_action_.reset( | 1993 browser_action_.reset( |
1908 LoadExtensionActionHelper(browser_action_value, error)); | 1994 LoadExtensionActionHelper(browser_action_value, error)); |
1909 if (!browser_action_.get()) | 1995 if (!browser_action_.get()) |
1910 return false; // Failed to parse browser action definition. | 1996 return false; // Failed to parse browser action definition. |
1911 } | 1997 } |
1912 | 1998 |
| 1999 // Initialize file browser actions (optional). |
| 2000 if (source.HasKey(keys::kFileBrowserActions)) { |
| 2001 ListValue* file_browser_actions_value = NULL; |
| 2002 if (!source.GetList(keys::kFileBrowserActions, |
| 2003 &file_browser_actions_value)) { |
| 2004 *error = errors::kInvalidFileBrowserAction; |
| 2005 return false; |
| 2006 } |
| 2007 |
| 2008 file_browser_actions_.reset( |
| 2009 LoadFileBrowserActions(file_browser_actions_value, error)); |
| 2010 if (!file_browser_actions_.get()) |
| 2011 return false; // Failed to parse file browser actions definition. |
| 2012 } |
| 2013 |
1913 // Load App settings. | 2014 // Load App settings. |
1914 if (!LoadIsApp(manifest_value_.get(), error) || | 2015 if (!LoadIsApp(manifest_value_.get(), error) || |
1915 !LoadExtent(manifest_value_.get(), keys::kWebURLs, | 2016 !LoadExtent(manifest_value_.get(), keys::kWebURLs, |
1916 &extent_, | 2017 &extent_, |
1917 errors::kInvalidWebURLs, errors::kInvalidWebURL, | 2018 errors::kInvalidWebURLs, errors::kInvalidWebURL, |
1918 parse_strictness, error) || | 2019 parse_strictness, error) || |
1919 !EnsureNotHybridApp(manifest_value_.get(), error) || | 2020 !EnsureNotHybridApp(manifest_value_.get(), error) || |
1920 !LoadLaunchURL(manifest_value_.get(), error) || | 2021 !LoadLaunchURL(manifest_value_.get(), error) || |
1921 !LoadLaunchContainer(manifest_value_.get(), error) || | 2022 !LoadLaunchContainer(manifest_value_.get(), error) || |
1922 !LoadAppIsolation(manifest_value_.get(), error)) { | 2023 !LoadAppIsolation(manifest_value_.get(), error)) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 std::string permission_str; | 2070 std::string permission_str; |
1970 if (!permissions->GetString(i, &permission_str)) { | 2071 if (!permissions->GetString(i, &permission_str)) { |
1971 *error = ExtensionErrorUtils::FormatErrorMessage( | 2072 *error = ExtensionErrorUtils::FormatErrorMessage( |
1972 errors::kInvalidPermission, base::IntToString(i)); | 2073 errors::kInvalidPermission, base::IntToString(i)); |
1973 return false; | 2074 return false; |
1974 } | 2075 } |
1975 | 2076 |
1976 // Only COMPONENT extensions can use private APIs. | 2077 // Only COMPONENT extensions can use private APIs. |
1977 // TODO(asargent) - We want a more general purpose mechanism for this, | 2078 // TODO(asargent) - We want a more general purpose mechanism for this, |
1978 // and better error messages. (http://crbug.com/54013) | 2079 // and better error messages. (http://crbug.com/54013) |
1979 if (!IsComponentOnlyPermission(permission_str)) { | 2080 if (!IsComponentOnlyPermission(permission_str) |
| 2081 #ifndef NDEBUG |
| 2082 && !CommandLine::ForCurrentProcess()->HasSwitch( |
| 2083 switches::kExposePrivateExtensionApi) |
| 2084 #endif |
| 2085 ) { |
1980 continue; | 2086 continue; |
1981 } | 2087 } |
1982 | 2088 |
1983 // Remap the old unlimited storage permission name. | 2089 // Remap the old unlimited storage permission name. |
1984 if (permission_str == kOldUnlimitedStoragePermission) | 2090 if (permission_str == kOldUnlimitedStoragePermission) |
1985 permission_str = kUnlimitedStoragePermission; | 2091 permission_str = kUnlimitedStoragePermission; |
1986 | 2092 |
1987 if (web_extent().is_empty() || location() == Extension::COMPONENT) { | 2093 if (web_extent().is_empty() || location() == Extension::COMPONENT) { |
1988 // Check if it's a module permission. If so, enable that permission. | 2094 // Check if it's a module permission. If so, enable that permission. |
1989 if (IsAPIPermission(permission_str)) { | 2095 if (IsAPIPermission(permission_str)) { |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2566 bool Extension::IsAPIPermission(const std::string& str) const { | 2672 bool Extension::IsAPIPermission(const std::string& str) const { |
2567 for (size_t i = 0; i < Extension::kNumPermissions; ++i) { | 2673 for (size_t i = 0; i < Extension::kNumPermissions; ++i) { |
2568 if (str == Extension::kPermissions[i].name) { | 2674 if (str == Extension::kPermissions[i].name) { |
2569 return true; | 2675 return true; |
2570 } | 2676 } |
2571 } | 2677 } |
2572 return false; | 2678 return false; |
2573 } | 2679 } |
2574 | 2680 |
2575 bool Extension::CanExecuteScriptEverywhere() const { | 2681 bool Extension::CanExecuteScriptEverywhere() const { |
2576 if (location() == Extension::COMPONENT) | 2682 if (location() == Extension::COMPONENT |
| 2683 #ifndef NDEBUG |
| 2684 || CommandLine::ForCurrentProcess()->HasSwitch( |
| 2685 switches::kExposePrivateExtensionApi) |
| 2686 #endif |
| 2687 ) |
2577 return true; | 2688 return true; |
2578 | 2689 |
2579 ScriptingWhitelist* whitelist = | 2690 ScriptingWhitelist* whitelist = |
2580 ExtensionConfig::GetInstance()->whitelist(); | 2691 ExtensionConfig::GetInstance()->whitelist(); |
2581 | 2692 |
2582 for (ScriptingWhitelist::const_iterator it = whitelist->begin(); | 2693 for (ScriptingWhitelist::const_iterator it = whitelist->begin(); |
2583 it != whitelist->end(); ++it) { | 2694 it != whitelist->end(); ++it) { |
2584 if (id() == *it) { | 2695 if (id() == *it) { |
2585 return true; | 2696 return true; |
2586 } | 2697 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2648 | 2759 |
2649 UninstalledExtensionInfo::~UninstalledExtensionInfo() {} | 2760 UninstalledExtensionInfo::~UninstalledExtensionInfo() {} |
2650 | 2761 |
2651 | 2762 |
2652 UnloadedExtensionInfo::UnloadedExtensionInfo( | 2763 UnloadedExtensionInfo::UnloadedExtensionInfo( |
2653 const Extension* extension, | 2764 const Extension* extension, |
2654 Reason reason) | 2765 Reason reason) |
2655 : reason(reason), | 2766 : reason(reason), |
2656 already_disabled(false), | 2767 already_disabled(false), |
2657 extension(extension) {} | 2768 extension(extension) {} |
OLD | NEW |