| Index: chrome/common/extensions/extension.cc
|
| diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
|
| index 1e84be7560bbf5313dc5b32322f2292a53eacef4..c68280fab48b4709a801289d3bcb7728fd1ec8c7 100644
|
| --- a/chrome/common/extensions/extension.cc
|
| +++ b/chrome/common/extensions/extension.cc
|
| @@ -34,7 +34,6 @@
|
| #include "chrome/common/extensions/extension_sidebar_defaults.h"
|
| #include "chrome/common/extensions/extension_sidebar_utils.h"
|
| #include "chrome/common/extensions/file_browser_handler.h"
|
| -#include "chrome/common/extensions/manifest.h"
|
| #include "chrome/common/extensions/user_script.h"
|
| #include "chrome/common/url_constants.h"
|
| #include "googleurl/src/url_util.h"
|
| @@ -86,6 +85,29 @@ static void ConvertHexadecimalToIDAlphabet(std::string* id) {
|
| }
|
| }
|
|
|
| +// These keys are allowed by all crx files (apps, extensions, themes, etc).
|
| +static const char* kBaseCrxKeys[] = {
|
| + keys::kCurrentLocale,
|
| + keys::kDefaultLocale,
|
| + keys::kDescription,
|
| + keys::kIcons,
|
| + keys::kManifestVersion,
|
| + keys::kName,
|
| + keys::kPublicKey,
|
| + keys::kSignature,
|
| + keys::kUpdateURL,
|
| + keys::kVersion,
|
| +};
|
| +
|
| +bool IsBaseCrxKey(const std::string& key) {
|
| + for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) {
|
| + if (key == kBaseCrxKeys[i])
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| // A singleton object containing global data needed by the extension objects.
|
| class ExtensionConfig {
|
| public:
|
| @@ -231,8 +253,7 @@ scoped_refptr<Extension> Extension::Create(const FilePath& path,
|
| DCHECK(error);
|
| scoped_refptr<Extension> extension = new Extension(path, location);
|
|
|
| - if (!extension->InitFromValue(new extensions::Manifest(value.DeepCopy()),
|
| - flags, error))
|
| + if (!extension->InitFromValue(value, flags, error))
|
| return NULL;
|
| return extension;
|
| }
|
| @@ -879,7 +900,31 @@ ExtensionSidebarDefaults* Extension::LoadExtensionSidebarDefaults(
|
| return result.release();
|
| }
|
|
|
| -bool Extension::LoadExtent(const extensions::Manifest* manifest,
|
| +bool Extension::ContainsNonThemeKeys(const DictionaryValue& source) const {
|
| + for (DictionaryValue::key_iterator key = source.begin_keys();
|
| + key != source.end_keys(); ++key) {
|
| + if (!IsBaseCrxKey(*key) && *key != keys::kTheme)
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool Extension::LoadIsApp(const DictionaryValue* manifest,
|
| + std::string* error) {
|
| + if (manifest->HasKey(keys::kApp))
|
| + is_app_ = true;
|
| +
|
| + if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnablePlatformApps)) {
|
| + if (manifest->HasKey(keys::kPlatformApp)) {
|
| + manifest->GetBoolean(keys::kPlatformApp, &is_platform_app_);
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +bool Extension::LoadExtent(const DictionaryValue* manifest,
|
| const char* key,
|
| URLPatternSet* extent,
|
| const char* list_error,
|
| @@ -956,7 +1001,7 @@ bool Extension::LoadExtent(const extensions::Manifest* manifest,
|
| return true;
|
| }
|
|
|
| -bool Extension::LoadLaunchURL(const extensions::Manifest* manifest,
|
| +bool Extension::LoadLaunchURL(const DictionaryValue* manifest,
|
| std::string* error) {
|
| Value* temp = NULL;
|
|
|
| @@ -1054,7 +1099,7 @@ bool Extension::LoadLaunchURL(const extensions::Manifest* manifest,
|
| return true;
|
| }
|
|
|
| -bool Extension::LoadLaunchContainer(const extensions::Manifest* manifest,
|
| +bool Extension::LoadLaunchContainer(const DictionaryValue* manifest,
|
| std::string* error) {
|
| Value* temp = NULL;
|
| if (!manifest->Get(keys::kLaunchContainer, &temp))
|
| @@ -1109,7 +1154,7 @@ bool Extension::LoadLaunchContainer(const extensions::Manifest* manifest,
|
| return true;
|
| }
|
|
|
| -bool Extension::LoadAppIsolation(const extensions::Manifest* manifest,
|
| +bool Extension::LoadAppIsolation(const DictionaryValue* manifest,
|
| std::string* error) {
|
| Value* temp = NULL;
|
| if (!manifest->Get(keys::kIsolation, &temp))
|
| @@ -1141,18 +1186,18 @@ bool Extension::LoadAppIsolation(const extensions::Manifest* manifest,
|
| return true;
|
| }
|
|
|
| -bool Extension::LoadWebIntentServices(const extensions::Manifest* manifest,
|
| +bool Extension::LoadWebIntentServices(const base::DictionaryValue& manifest,
|
| std::string* error) {
|
| DCHECK(error);
|
|
|
| if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents))
|
| return true;
|
|
|
| - if (!manifest->HasKey(keys::kIntents))
|
| + if (!manifest.HasKey(keys::kIntents))
|
| return true;
|
|
|
| DictionaryValue* all_services = NULL;
|
| - if (!manifest->GetDictionary(keys::kIntents, &all_services)) {
|
| + if (!manifest.GetDictionary(keys::kIntents, &all_services)) {
|
| *error = errors::kInvalidIntents;
|
| return false;
|
| }
|
| @@ -1211,6 +1256,32 @@ bool Extension::LoadWebIntentServices(const extensions::Manifest* manifest,
|
| return true;
|
| }
|
|
|
| +
|
| +bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest,
|
| + std::string* error) {
|
| + if (web_extent().is_empty())
|
| + return true;
|
| +
|
| + for (DictionaryValue::key_iterator key = manifest->begin_keys();
|
| + key != manifest->end_keys(); ++key) {
|
| + if (!IsBaseCrxKey(*key) &&
|
| + *key != keys::kApp &&
|
| + *key != keys::kPermissions &&
|
| + *key != keys::kOptionalPermissions &&
|
| + *key != keys::kOptionsPage &&
|
| + *key != keys::kBackground &&
|
| + *key != keys::kOfflineEnabled &&
|
| + *key != keys::kMinimumChromeVersion &&
|
| + *key != keys::kRequirements) {
|
| + *error = ExtensionErrorUtils::FormatErrorMessage(
|
| + errors::kHostedAppsCannotIncludeExtensionFeatures, *key);
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| // static
|
| bool Extension::IsTrustedId(const std::string& id) {
|
| // See http://b/4946060 for more details.
|
| @@ -1223,6 +1294,9 @@ Extension::Extension(const FilePath& path, Location location)
|
| offline_enabled_(false),
|
| location_(location),
|
| converted_from_user_script_(false),
|
| + is_theme_(false),
|
| + is_app_(false),
|
| + is_platform_app_(false),
|
| is_storage_isolated_(false),
|
| launch_container_(extension_misc::LAUNCH_TAB),
|
| launch_width_(0),
|
| @@ -1381,14 +1455,10 @@ GURL Extension::GetBaseURLFromExtensionId(const std::string& extension_id) {
|
| chrome::kStandardSchemeSeparator + extension_id + "/");
|
| }
|
|
|
| -bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| +bool Extension::InitFromValue(const DictionaryValue& source, int flags,
|
| std::string* error) {
|
| DCHECK(error);
|
| base::AutoLock auto_lock(runtime_data_lock_);
|
| -
|
| - if (!manifest->ValidateManifest(error))
|
| - return false;
|
| -
|
| // When strict error checks are enabled, make URL pattern parsing strict.
|
| URLPattern::ParseOption parse_strictness =
|
| (flags & STRICT_ERROR_CHECKS ? URLPattern::ERROR_ON_PORTS
|
| @@ -1399,9 +1469,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| optional_permission_set_ = new ExtensionPermissionSet();
|
| required_permission_set_ = new ExtensionPermissionSet();
|
|
|
| - if (manifest->HasKey(keys::kManifestVersion)) {
|
| + if (source.HasKey(keys::kManifestVersion)) {
|
| int manifest_version = 0;
|
| - if (!manifest->GetInteger(keys::kManifestVersion, &manifest_version) ||
|
| + if (!source.GetInteger(keys::kManifestVersion, &manifest_version) ||
|
| manifest_version < 1) {
|
| *error = errors::kInvalidManifestVersion;
|
| return false;
|
| @@ -1420,10 +1490,10 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| return false;
|
| }
|
|
|
| - if (manifest->HasKey(keys::kPublicKey)) {
|
| + if (source.HasKey(keys::kPublicKey)) {
|
| std::string public_key_bytes;
|
| - if (!manifest->GetString(keys::kPublicKey,
|
| - &public_key_) ||
|
| + if (!source.GetString(keys::kPublicKey,
|
| + &public_key_) ||
|
| !ParsePEMKeyBytes(public_key_,
|
| &public_key_bytes) ||
|
| !GenerateId(public_key_bytes, &id_)) {
|
| @@ -1446,14 +1516,15 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
|
|
| creation_flags_ = flags;
|
|
|
| - manifest_.reset(manifest);
|
| + // Make a copy of the manifest so we can store it in prefs.
|
| + manifest_value_.reset(source.DeepCopy());
|
|
|
| // Initialize the URL.
|
| extension_url_ = Extension::GetBaseURLFromExtensionId(id());
|
|
|
| // Initialize version.
|
| std::string version_str;
|
| - if (!manifest->GetString(keys::kVersion, &version_str)) {
|
| + if (!source.GetString(keys::kVersion, &version_str)) {
|
| *error = errors::kInvalidVersion;
|
| return false;
|
| }
|
| @@ -1466,7 +1537,7 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
|
|
| // Initialize name.
|
| string16 localized_name;
|
| - if (!manifest->GetString(keys::kName, &localized_name)) {
|
| + if (!source.GetString(keys::kName, &localized_name)) {
|
| *error = errors::kInvalidName;
|
| return false;
|
| }
|
| @@ -1476,17 +1547,18 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| // Load App settings. LoadExtent at least has to be done before
|
| // ParsePermissions(), because the valid permissions depend on what type of
|
| // package this is.
|
| - if (is_app() &&
|
| - (!LoadExtent(manifest_.get(), keys::kWebURLs,
|
| - &extent_,
|
| - errors::kInvalidWebURLs, errors::kInvalidWebURL,
|
| - parse_strictness, error) ||
|
| - !LoadLaunchURL(manifest_.get(), error) ||
|
| - !LoadLaunchContainer(manifest_.get(), error))) {
|
| + if (!LoadIsApp(manifest_value_.get(), error) ||
|
| + !LoadExtent(manifest_value_.get(), keys::kWebURLs,
|
| + &extent_,
|
| + errors::kInvalidWebURLs, errors::kInvalidWebURL,
|
| + parse_strictness, error) ||
|
| + !EnsureNotHybridApp(manifest_value_.get(), error) ||
|
| + !LoadLaunchURL(manifest_value_.get(), error) ||
|
| + !LoadLaunchContainer(manifest_value_.get(), error)) {
|
| return false;
|
| }
|
|
|
| - if (is_platform_app()) {
|
| + if (is_platform_app_) {
|
| if (launch_container() != extension_misc::LAUNCH_SHELL) {
|
| *error = errors::kInvalidLaunchContainerForPlatform;
|
| return false;
|
| @@ -1499,7 +1571,7 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| // Initialize the permissions (optional).
|
| ExtensionAPIPermissionSet api_permissions;
|
| URLPatternSet host_permissions;
|
| - if (!ParsePermissions(manifest_.get(),
|
| + if (!ParsePermissions(&source,
|
| keys::kPermissions,
|
| flags,
|
| error,
|
| @@ -1511,7 +1583,7 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| // Initialize the optional permissions (optional).
|
| ExtensionAPIPermissionSet optional_api_permissions;
|
| URLPatternSet optional_host_permissions;
|
| - if (!ParsePermissions(manifest_.get(),
|
| + if (!ParsePermissions(&source,
|
| keys::kOptionalPermissions,
|
| flags,
|
| error,
|
| @@ -1521,8 +1593,8 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize description (if present).
|
| - if (manifest->HasKey(keys::kDescription)) {
|
| - if (!manifest->GetString(keys::kDescription,
|
| + if (source.HasKey(keys::kDescription)) {
|
| + if (!source.GetString(keys::kDescription,
|
| &description_)) {
|
| *error = errors::kInvalidDescription;
|
| return false;
|
| @@ -1530,9 +1602,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize homepage url (if present).
|
| - if (manifest->HasKey(keys::kHomepageURL)) {
|
| + if (source.HasKey(keys::kHomepageURL)) {
|
| std::string tmp;
|
| - if (!manifest->GetString(keys::kHomepageURL, &tmp)) {
|
| + if (!source.GetString(keys::kHomepageURL, &tmp)) {
|
| *error = ExtensionErrorUtils::FormatErrorMessage(
|
| errors::kInvalidHomepageURL, "");
|
| return false;
|
| @@ -1548,9 +1620,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize update url (if present).
|
| - if (manifest->HasKey(keys::kUpdateURL)) {
|
| + if (source.HasKey(keys::kUpdateURL)) {
|
| std::string tmp;
|
| - if (!manifest->GetString(keys::kUpdateURL, &tmp)) {
|
| + if (!source.GetString(keys::kUpdateURL, &tmp)) {
|
| *error = ExtensionErrorUtils::FormatErrorMessage(
|
| errors::kInvalidUpdateURL, "");
|
| return false;
|
| @@ -1566,9 +1638,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
|
|
| // Validate minimum Chrome version (if present). We don't need to store this,
|
| // since the extension is not valid if it is incorrect.
|
| - if (manifest->HasKey(keys::kMinimumChromeVersion)) {
|
| + if (source.HasKey(keys::kMinimumChromeVersion)) {
|
| std::string minimum_version_string;
|
| - if (!manifest->GetString(keys::kMinimumChromeVersion,
|
| + if (!source.GetString(keys::kMinimumChromeVersion,
|
| &minimum_version_string)) {
|
| *error = errors::kInvalidMinimumChromeVersion;
|
| return false;
|
| @@ -1604,14 +1676,13 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize converted_from_user_script (if present)
|
| - if (manifest->HasKey(keys::kConvertedFromUserScript))
|
| - manifest->GetBoolean(keys::kConvertedFromUserScript,
|
| - &converted_from_user_script_);
|
| + source.GetBoolean(keys::kConvertedFromUserScript,
|
| + &converted_from_user_script_);
|
|
|
| // Initialize icons (if present).
|
| - if (manifest->HasKey(keys::kIcons)) {
|
| + if (source.HasKey(keys::kIcons)) {
|
| DictionaryValue* icons_value = NULL;
|
| - if (!manifest->GetDictionary(keys::kIcons, &icons_value)) {
|
| + if (!source.GetDictionary(keys::kIcons, &icons_value)) {
|
| *error = errors::kInvalidIcons;
|
| return false;
|
| }
|
| @@ -1641,12 +1712,20 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize themes (if present).
|
| - if (manifest->HasKey(keys::kTheme)) {
|
| + is_theme_ = false;
|
| + if (source.HasKey(keys::kTheme)) {
|
| + // Themes cannot contain extension keys.
|
| + if (ContainsNonThemeKeys(source)) {
|
| + *error = errors::kThemesCannotContainExtensions;
|
| + return false;
|
| + }
|
| +
|
| DictionaryValue* theme_value = NULL;
|
| - if (!manifest->GetDictionary(keys::kTheme, &theme_value)) {
|
| + if (!source.GetDictionary(keys::kTheme, &theme_value)) {
|
| *error = errors::kInvalidTheme;
|
| return false;
|
| }
|
| + is_theme_ = true;
|
|
|
| DictionaryValue* images_value = NULL;
|
| if (theme_value->GetDictionary(keys::kThemeImages, &images_value)) {
|
| @@ -1719,9 +1798,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize plugins (optional).
|
| - if (manifest->HasKey(keys::kPlugins)) {
|
| + if (source.HasKey(keys::kPlugins)) {
|
| ListValue* list_value = NULL;
|
| - if (!manifest->GetList(keys::kPlugins, &list_value)) {
|
| + if (!source.GetList(keys::kPlugins, &list_value)) {
|
| *error = errors::kInvalidPlugins;
|
| return false;
|
| }
|
| @@ -1763,9 +1842,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
| }
|
|
|
| - if (manifest->HasKey(keys::kNaClModules)) {
|
| + if (source.HasKey(keys::kNaClModules)) {
|
| ListValue* list_value = NULL;
|
| - if (!manifest->GetList(keys::kNaClModules, &list_value)) {
|
| + if (!source.GetList(keys::kNaClModules, &list_value)) {
|
| *error = errors::kInvalidNaClModules;
|
| return false;
|
| }
|
| @@ -1801,9 +1880,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize content scripts (optional).
|
| - if (manifest->HasKey(keys::kContentScripts)) {
|
| + if (source.HasKey(keys::kContentScripts)) {
|
| ListValue* list_value;
|
| - if (!manifest->GetList(keys::kContentScripts, &list_value)) {
|
| + if (!source.GetList(keys::kContentScripts, &list_value)) {
|
| *error = errors::kInvalidContentScriptsList;
|
| return false;
|
| }
|
| @@ -1831,9 +1910,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| // Initialize page action (optional).
|
| DictionaryValue* page_action_value = NULL;
|
|
|
| - if (manifest->HasKey(keys::kPageActions)) {
|
| + if (source.HasKey(keys::kPageActions)) {
|
| ListValue* list_value = NULL;
|
| - if (!manifest->GetList(keys::kPageActions, &list_value)) {
|
| + if (!source.GetList(keys::kPageActions, &list_value)) {
|
| *error = errors::kInvalidPageActionsList;
|
| return false;
|
| }
|
| @@ -1852,8 +1931,8 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| *error = errors::kInvalidPageActionsListSize;
|
| return false;
|
| }
|
| - } else if (manifest->HasKey(keys::kPageAction)) {
|
| - if (!manifest->GetDictionary(keys::kPageAction, &page_action_value)) {
|
| + } else if (source.HasKey(keys::kPageAction)) {
|
| + if (!source.GetDictionary(keys::kPageAction, &page_action_value)) {
|
| *error = errors::kInvalidPageAction;
|
| return false;
|
| }
|
| @@ -1868,9 +1947,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize browser action (optional).
|
| - if (manifest->HasKey(keys::kBrowserAction)) {
|
| + if (source.HasKey(keys::kBrowserAction)) {
|
| DictionaryValue* browser_action_value = NULL;
|
| - if (!manifest->GetDictionary(keys::kBrowserAction, &browser_action_value)) {
|
| + if (!source.GetDictionary(keys::kBrowserAction, &browser_action_value)) {
|
| *error = errors::kInvalidBrowserAction;
|
| return false;
|
| }
|
| @@ -1882,9 +1961,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize file browser actions (optional).
|
| - if (manifest->HasKey(keys::kFileBrowserHandlers)) {
|
| + if (source.HasKey(keys::kFileBrowserHandlers)) {
|
| ListValue* file_browser_handlers_value = NULL;
|
| - if (!manifest->GetList(keys::kFileBrowserHandlers,
|
| + if (!source.GetList(keys::kFileBrowserHandlers,
|
| &file_browser_handlers_value)) {
|
| *error = errors::kInvalidFileBrowserHandler;
|
| return false;
|
| @@ -1898,14 +1977,15 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
|
|
| // App isolation.
|
| if (api_permissions.count(ExtensionAPIPermission::kExperimental)) {
|
| - if (is_app() && !LoadAppIsolation(manifest_.get(), error))
|
| + if (!LoadAppIsolation(manifest_value_.get(), error))
|
| return false;
|
| }
|
|
|
| // Initialize options page url (optional).
|
| - if (manifest->HasKey(keys::kOptionsPage)) {
|
| + // Function LoadIsApp() set is_app_ above.
|
| + if (source.HasKey(keys::kOptionsPage)) {
|
| std::string options_str;
|
| - if (!manifest->GetString(keys::kOptionsPage, &options_str)) {
|
| + if (!source.GetString(keys::kOptionsPage, &options_str)) {
|
| *error = errors::kInvalidOptionsPage;
|
| return false;
|
| }
|
| @@ -1934,9 +2014,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize background url (optional).
|
| - if (manifest->HasKey(keys::kBackground)) {
|
| + if (source.HasKey(keys::kBackground)) {
|
| std::string background_str;
|
| - if (!manifest->GetString(keys::kBackground, &background_str)) {
|
| + if (!source.GetString(keys::kBackground, &background_str)) {
|
| *error = errors::kInvalidBackground;
|
| return false;
|
| }
|
| @@ -1967,8 +2047,8 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
| }
|
|
|
| - if (manifest->HasKey(keys::kDefaultLocale)) {
|
| - if (!manifest->GetString(keys::kDefaultLocale, &default_locale_) ||
|
| + if (source.HasKey(keys::kDefaultLocale)) {
|
| + if (!source.GetString(keys::kDefaultLocale, &default_locale_) ||
|
| !l10n_util::IsValidLocaleSyntax(default_locale_)) {
|
| *error = errors::kInvalidDefaultLocale;
|
| return false;
|
| @@ -1976,9 +2056,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Chrome URL overrides (optional)
|
| - if (manifest->HasKey(keys::kChromeURLOverrides)) {
|
| + if (source.HasKey(keys::kChromeURLOverrides)) {
|
| DictionaryValue* overrides = NULL;
|
| - if (!manifest->GetDictionary(keys::kChromeURLOverrides, &overrides)) {
|
| + if (!source.GetDictionary(keys::kChromeURLOverrides, &overrides)) {
|
| *error = errors::kInvalidChromeURLOverrides;
|
| return false;
|
| }
|
| @@ -2020,9 +2100,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| if (api_permissions.count(ExtensionAPIPermission::kExperimental) &&
|
| - manifest->HasKey(keys::kInputComponents)) {
|
| + source.HasKey(keys::kInputComponents)) {
|
| ListValue* list_value = NULL;
|
| - if (!manifest->GetList(keys::kInputComponents, &list_value)) {
|
| + if (!source.GetList(keys::kInputComponents, &list_value)) {
|
| *error = errors::kInvalidInputComponents;
|
| return false;
|
| }
|
| @@ -2151,17 +2231,17 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
| }
|
|
|
| - if (manifest->HasKey(keys::kOmnibox)) {
|
| - if (!manifest->GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
|
| + if (source.HasKey(keys::kOmnibox)) {
|
| + if (!source.GetString(keys::kOmniboxKeyword, &omnibox_keyword_) ||
|
| omnibox_keyword_.empty()) {
|
| *error = errors::kInvalidOmniboxKeyword;
|
| return false;
|
| }
|
| }
|
|
|
| - if (manifest->HasKey(keys::kContentSecurityPolicy)) {
|
| + if (source.HasKey(keys::kContentSecurityPolicy)) {
|
| std::string content_security_policy;
|
| - if (!manifest->GetString(keys::kContentSecurityPolicy,
|
| + if (!source.GetString(keys::kContentSecurityPolicy,
|
| &content_security_policy)) {
|
| *error = errors::kInvalidContentSecurityPolicy;
|
| return false;
|
| @@ -2186,9 +2266,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize devtools page url (optional).
|
| - if (manifest->HasKey(keys::kDevToolsPage)) {
|
| + if (source.HasKey(keys::kDevToolsPage)) {
|
| std::string devtools_str;
|
| - if (!manifest->GetString(keys::kDevToolsPage, &devtools_str)) {
|
| + if (!source.GetString(keys::kDevToolsPage, &devtools_str)) {
|
| *error = errors::kInvalidDevToolsPage;
|
| return false;
|
| }
|
| @@ -2200,9 +2280,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize sidebar action (optional).
|
| - if (manifest->HasKey(keys::kSidebar)) {
|
| + if (source.HasKey(keys::kSidebar)) {
|
| DictionaryValue* sidebar_value = NULL;
|
| - if (!manifest->GetDictionary(keys::kSidebar, &sidebar_value)) {
|
| + if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) {
|
| *error = errors::kInvalidSidebar;
|
| return false;
|
| }
|
| @@ -2216,9 +2296,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize text-to-speech voices (optional).
|
| - if (manifest->HasKey(keys::kTtsEngine)) {
|
| + if (source.HasKey(keys::kTtsEngine)) {
|
| DictionaryValue* tts_dict = NULL;
|
| - if (!manifest->GetDictionary(keys::kTtsEngine, &tts_dict)) {
|
| + if (!source.GetDictionary(keys::kTtsEngine, &tts_dict)) {
|
| *error = errors::kInvalidTts;
|
| return false;
|
| }
|
| @@ -2299,15 +2379,15 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize web intents (optional).
|
| - if (!LoadWebIntentServices(manifest, error))
|
| + if (!LoadWebIntentServices(source, error))
|
| return false;
|
|
|
| // Initialize incognito behavior. Apps default to split mode, extensions
|
| // default to spanning.
|
| incognito_split_mode_ = is_app();
|
| - if (manifest->HasKey(keys::kIncognito)) {
|
| + if (source.HasKey(keys::kIncognito)) {
|
| std::string value;
|
| - if (!manifest->GetString(keys::kIncognito, &value)) {
|
| + if (!source.GetString(keys::kIncognito, &value)) {
|
| *error = errors::kInvalidIncognitoBehavior;
|
| return false;
|
| }
|
| @@ -2322,8 +2402,8 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| }
|
|
|
| // Initialize offline-enabled status. Defaults to false.
|
| - if (manifest->HasKey(keys::kOfflineEnabled)) {
|
| - if (!manifest->GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) {
|
| + if (source.HasKey(keys::kOfflineEnabled)) {
|
| + if (!source.GetBoolean(keys::kOfflineEnabled, &offline_enabled_)) {
|
| *error = errors::kInvalidOfflineEnabled;
|
| return false;
|
| }
|
| @@ -2331,9 +2411,9 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
|
|
| // Initialize requirements (optional). Not actually persisted (they're only
|
| // used by the store), but still validated.
|
| - if (manifest->HasKey(keys::kRequirements)) {
|
| + if (source.HasKey(keys::kRequirements)) {
|
| DictionaryValue* requirements_value = NULL;
|
| - if (!manifest->GetDictionary(keys::kRequirements, &requirements_value)) {
|
| + if (!source.GetDictionary(keys::kRequirements, &requirements_value)) {
|
| *error = errors::kInvalidRequirements;
|
| return false;
|
| }
|
| @@ -2362,6 +2442,13 @@ bool Extension::InitFromValue(extensions::Manifest* manifest, int flags,
|
| optional_permission_set_ = new ExtensionPermissionSet(
|
| optional_api_permissions, optional_host_permissions, URLPatternSet());
|
|
|
| + // Although |source| is passed in as a const, it's still possible to modify
|
| + // it. This is dangerous since the utility process re-uses |source| after
|
| + // it calls InitFromValue, passing it up to the browser process which calls
|
| + // InitFromValue again. As a result, we need to make sure that nobody
|
| + // accidentally modifies it.
|
| + DCHECK(source.Equals(manifest_value_.get()));
|
| +
|
| return true;
|
| }
|
|
|
| @@ -2517,7 +2604,7 @@ GURL Extension::GetIconURL(int size,
|
| return GetResourceURL(path);
|
| }
|
|
|
| -bool Extension::ParsePermissions(const extensions::Manifest* source,
|
| +bool Extension::ParsePermissions(const DictionaryValue* source,
|
| const char* key,
|
| int flags,
|
| std::string* error,
|
|
|