summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-02 22:46:47 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-02 22:46:47 +0000
commit6d1c43b3e0324f6e870d9fc642f6135d990aee26 (patch)
treef263ef45ec4cff6e6e88ae39d64459b26360f6e7 /chrome/common
parent73dca1b6e24c63f52cc2aaf44afdfb7c21df93a1 (diff)
downloadchromium_src-6d1c43b3e0324f6e870d9fc642f6135d990aee26.zip
chromium_src-6d1c43b3e0324f6e870d9fc642f6135d990aee26.tar.gz
chromium_src-6d1c43b3e0324f6e870d9fc642f6135d990aee26.tar.bz2
Revert "Restrict extension features based on the extension type."
This breaks some ChromeOS tests. Among the log output: "Feature 'chrome_url_overrides' is not allowed in this type of manifest." Original review: http://codereview.chromium.org/8654001 BUG=101992, 104103, chromium-os:23709 TEST=no Review URL: http://codereview.chromium.org/8786004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112808 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/extensions/extension.cc269
-rw-r--r--chrome/common/extensions/extension.h52
-rw-r--r--chrome/common/extensions/extension_constants.cc6
-rw-r--r--chrome/common/extensions/extension_constants.h3
-rw-r--r--chrome/common/extensions/extension_manifests_unittest.cc12
-rw-r--r--chrome/common/extensions/extension_messages.cc6
-rw-r--r--chrome/common/extensions/manifest.cc229
-rw-r--r--chrome/common/extensions/manifest.h112
-rw-r--r--chrome/common/extensions/manifest_unittest.cc392
9 files changed, 228 insertions, 853 deletions
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 1e84be7..c68280f 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,
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 54bff60..a0ec6d8 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -20,7 +20,6 @@
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_permission_set.h"
-#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/user_script.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/extensions/url_pattern_set.h"
@@ -375,7 +374,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// Parses the host and api permissions from the specified permission |key|
// in the manifest |source|.
- bool ParsePermissions(const extensions::Manifest* source,
+ bool ParsePermissions(const base::DictionaryValue* source,
const char* key,
int flags,
std::string* error,
@@ -532,8 +531,8 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
}
const GURL& update_url() const { return update_url_; }
const ExtensionIconSet& icons() const { return icons_; }
- const extensions::Manifest* manifest() const {
- return manifest_.get();
+ const base::DictionaryValue* manifest_value() const {
+ return manifest_value_.get();
}
const std::string default_locale() const { return default_locale_; }
const URLOverrideMap& GetChromeURLOverrides() const {
@@ -558,12 +557,12 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
}
// App-related.
- bool is_app() const {
- return is_packaged_app() || is_hosted_app() || is_platform_app();
+ bool is_app() const { return is_app_; }
+ bool is_platform_app() const { return is_platform_app_; }
+ bool is_hosted_app() const { return is_app() && !web_extent().is_empty(); }
+ bool is_packaged_app() const {
+ return !is_platform_app() && is_app() && web_extent().is_empty();
}
- bool is_platform_app() const { return manifest()->IsPlatformApp(); }
- bool is_hosted_app() const { return manifest()->IsHostedApp(); }
- bool is_packaged_app() const { return manifest()->IsPackagedApp(); }
bool is_storage_isolated() const { return is_app() && is_storage_isolated_; }
const URLPatternSet& web_extent() const { return extent_; }
const std::string& launch_local_path() const { return launch_local_path_; }
@@ -575,7 +574,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
int launch_height() const { return launch_height_; }
// Theme-related.
- bool is_theme() const { return manifest()->IsTheme(); }
+ bool is_theme() const { return is_theme_; }
base::DictionaryValue* GetThemeImages() const { return theme_images_.get(); }
base::DictionaryValue* GetThemeColors() const {return theme_colors_.get(); }
base::DictionaryValue* GetThemeTints() const { return theme_tints_.get(); }
@@ -617,8 +616,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
~Extension();
// Initialize the extension from a parsed manifest.
- // Takes ownership of the manifest |value|.
- bool InitFromValue(extensions::Manifest* value, int flags,
+ bool InitFromValue(const base::DictionaryValue& value, int flags,
std::string* error);
// Helper function for implementing HasCachedImage/GetCachedImage. A return
@@ -645,21 +643,24 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
UserScript *instance);
// Helpers to load various chunks of the manifest.
- bool LoadExtent(const extensions::Manifest* manifest,
+ bool LoadIsApp(const base::DictionaryValue* manifest, std::string* error);
+ bool LoadExtent(const base::DictionaryValue* manifest,
const char* key,
URLPatternSet* extent,
const char* list_error,
const char* value_error,
URLPattern::ParseOption parse_strictness,
std::string* error);
- bool LoadLaunchContainer(const extensions::Manifest* manifest,
+ bool LoadLaunchContainer(const base::DictionaryValue* manifest,
std::string* error);
- bool LoadLaunchURL(const extensions::Manifest* manifest,
+ bool LoadLaunchURL(const base::DictionaryValue* manifest,
std::string* error);
- bool LoadAppIsolation(const extensions::Manifest* manifest,
+ bool LoadAppIsolation(const base::DictionaryValue* manifest,
std::string* error);
- bool LoadWebIntentServices(const extensions::Manifest* manifest,
+ bool LoadWebIntentServices(const base::DictionaryValue& manifest,
std::string* error);
+ bool EnsureNotHybridApp(const base::DictionaryValue* manifest,
+ std::string* error);
// Helper method to load an ExtensionAction from the page_action or
// browser_action entries in the manifest.
@@ -682,6 +683,10 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// an extension that has a browser action and a page action.
bool HasMultipleUISurfaces() const;
+ // Figures out if a source contains keys not associated with themes - we
+ // don't want to allow scripts and such to be bundled with themes.
+ bool ContainsNonThemeKeys(const base::DictionaryValue& source) const;
+
// Updates the launch URL and extents for the extension using the given
// |override_url|.
void OverrideLaunchUrl(const GURL& override_url);
@@ -815,6 +820,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// A map of display properties.
scoped_ptr<base::DictionaryValue> theme_display_properties_;
+ // Whether the extension is a theme.
+ bool is_theme_;
+
// The homepage for this extension. Useful if it is not hosted by Google and
// therefore does not have a Gallery URL.
GURL homepage_url_;
@@ -822,13 +830,19 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// URL for fetching an update manifest
GURL update_url_;
- // The manifest that this extension was created from.
- scoped_ptr<extensions::Manifest> manifest_;
+ // A copy of the manifest that this extension was created from.
+ scoped_ptr<base::DictionaryValue> manifest_value_;
// A map of chrome:// hostnames (newtab, downloads, etc.) to Extension URLs
// which override the handling of those URLs. (see ExtensionOverrideUI).
URLOverrideMap chrome_url_overrides_;
+ // Whether this extension uses app features.
+ bool is_app_;
+
+ // Whether this app uses platform features.
+ bool is_platform_app_;
+
// Whether this extension requests isolated storage.
bool is_storage_isolated_;
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index f818e62..2d0e730 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -166,8 +166,8 @@ const char kExpectString[] = "Expect string value.";
const char kExperimentalFlagRequired[] =
"Loading extensions with 'experimental' permission requires"
" --enable-experimental-extension-apis command line flag.";
-const char kFeatureNotAllowed[] =
- "Feature '*' is not allowed in this type of manifest.";
+const char kHostedAppsCannotIncludeExtensionFeatures[] =
+ "Hosted apps cannot use the extension feature '*'.";
const char kInvalidAllFrames[] =
"Invalid value for 'content_scripts[*].all_frames'.";
const char kInvalidBackground[] =
@@ -429,6 +429,8 @@ const char kReservedMessageFound[] =
const char kSidebarExperimental[] =
"You must request the 'experimental' permission in order to use the"
" Sidebar API.";
+const char kThemesCannotContainExtensions[] =
+ "A theme cannot contain extensions code.";
#if defined(OS_CHROMEOS)
const char kIllegalPlugins[] =
"Extensions cannot install plugins on Chrome OS";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index abb77f0..8c988f3 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -150,7 +150,7 @@ namespace extension_manifest_errors {
extern const char kDisabledByPolicy[];
extern const char kExperimentalFlagRequired[];
extern const char kExpectString[];
- extern const char kFeatureNotAllowed[];
+ extern const char kHostedAppsCannotIncludeExtensionFeatures[];
extern const char kInvalidAllFrames[];
extern const char kInvalidBackground[];
extern const char kInvalidBackgroundInHostedApp[];
@@ -280,6 +280,7 @@ namespace extension_manifest_errors {
extern const char kOneUISurfaceOnly[];
extern const char kReservedMessageFound[];
extern const char kSidebarExperimental[];
+ extern const char kThemesCannotContainExtensions[];
extern const char kWebContentMustBeEnabled[];
#if defined(OS_CHROMEOS)
extern const char kIllegalPlugins[];
diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc
index 8136dea..adc6969 100644
--- a/chrome/common/extensions/extension_manifests_unittest.cc
+++ b/chrome/common/extensions/extension_manifests_unittest.cc
@@ -588,8 +588,12 @@ TEST_F(ExtensionManifestTest, Sidebar) {
extension->sidebar_defaults()->default_page().spec());
}
-TEST_F(ExtensionManifestTest, BackgroundPermission) {
- LoadAndExpectError("background_permission.json",
+TEST_F(ExtensionManifestTest, DisallowHybridApps) {
+ LoadAndExpectError("disallow_hybrid_1.json",
+ ExtensionErrorUtils::FormatErrorMessage(
+ errors::kHostedAppsCannotIncludeExtensionFeatures,
+ keys::kBrowserAction));
+ LoadAndExpectError("disallow_hybrid_2.json",
errors::kBackgroundPermissionNeeded);
}
@@ -738,7 +742,9 @@ TEST_F(ExtensionManifestTest, NormalizeIconPaths) {
}
TEST_F(ExtensionManifestTest, DisallowMultipleUISurfaces) {
- LoadAndExpectError("multiple_ui_surfaces.json", errors::kOneUISurfaceOnly);
+ LoadAndExpectError("multiple_ui_surfaces_1.json", errors::kOneUISurfaceOnly);
+ LoadAndExpectError("multiple_ui_surfaces_2.json", errors::kOneUISurfaceOnly);
+ LoadAndExpectError("multiple_ui_surfaces_3.json", errors::kOneUISurfaceOnly);
}
TEST_F(ExtensionManifestTest, ParseHomepageURLs) {
diff --git a/chrome/common/extensions/extension_messages.cc b/chrome/common/extensions/extension_messages.cc
index 3adee27..a326289 100644
--- a/chrome/common/extensions/extension_messages.cc
+++ b/chrome/common/extensions/extension_messages.cc
@@ -5,7 +5,6 @@
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/manifest.h"
#include "content/public/common/common_param_traits.h"
ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params()
@@ -50,11 +49,10 @@ ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params(
extension_manifest_keys::kVersion,
};
- // Copy only the data we need and bypass the manifest type checks.
- DictionaryValue* source = extension->manifest()->value();
+ // Copy only the data we need.
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRendererExtensionKeys); ++i) {
Value* temp = NULL;
- if (source->Get(kRendererExtensionKeys[i], &temp))
+ if (extension->manifest_value()->Get(kRendererExtensionKeys[i], &temp))
manifest->Set(kRendererExtensionKeys[i], temp->DeepCopy());
}
}
diff --git a/chrome/common/extensions/manifest.cc b/chrome/common/extensions/manifest.cc
deleted file mode 100644
index 7f05bb6..0000000
--- a/chrome/common/extensions/manifest.cc
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/common/extensions/manifest.h"
-
-#include "base/basictypes.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/string_split.h"
-#include "base/values.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_error_utils.h"
-
-namespace errors = extension_manifest_errors;
-namespace keys = extension_manifest_keys;
-
-namespace extensions {
-
-namespace {
-
-typedef std::map<std::string, int> RestrictionMap;
-
-struct Restrictions {
- Restrictions() {
- // Base keys that all manifests can specify.
- map[keys::kName] = Manifest::kTypeAll;
- map[keys::kVersion] = Manifest::kTypeAll;
- map[keys::kManifestVersion] = Manifest::kTypeAll;
- map[keys::kDescription] = Manifest::kTypeAll;
- map[keys::kIcons] = Manifest::kTypeAll;
- map[keys::kCurrentLocale] = Manifest::kTypeAll;
- map[keys::kDefaultLocale] = Manifest::kTypeAll;
- map[keys::kSignature] = Manifest::kTypeAll;
- map[keys::kUpdateURL] = Manifest::kTypeAll;
- map[keys::kPublicKey] = Manifest::kTypeAll;
-
- // Type specific.
- map[keys::kApp] = Manifest::kTypeHostedApp | Manifest::kTypePackagedApp |
- Manifest::kTypePlatformApp;
- map[keys::kTheme] = Manifest::kTypeTheme;
-
- // keys::kPlatformApp holds a boolean, so all types can define it.
- map[keys::kPlatformApp] = Manifest::kTypeAll;
-
- // Extensions only.
- map[keys::kBrowserAction] = Manifest::kTypeExtension;
- map[keys::kPageAction] = Manifest::kTypeExtension;
- map[keys::kPageActions] = Manifest::kTypeExtension;
- map[keys::kChromeURLOverrides] = Manifest::kTypeExtension;
-
- // Everything except themes.
- int all_but_themes = Manifest::kTypeAll - Manifest::kTypeTheme;
- map[keys::kPermissions] = all_but_themes;
- map[keys::kOptionalPermissions] = all_but_themes;
- map[keys::kOptionsPage] = all_but_themes;
- map[keys::kBackground] = all_but_themes;
- map[keys::kOfflineEnabled] = all_but_themes;
- map[keys::kMinimumChromeVersion] = all_but_themes;
- map[keys::kRequirements] = all_but_themes;
- map[keys::kConvertedFromUserScript] = all_but_themes;
- map[keys::kNaClModules] = all_but_themes;
- map[keys::kPlugins] = all_but_themes;
-
- // Extensions and packaged apps.
- int ext_and_packaged =
- Manifest::kTypeExtension | Manifest::kTypePackagedApp;
- map[keys::kContentScripts] = ext_and_packaged;
- map[keys::kOmnibox] = ext_and_packaged;
- map[keys::kDevToolsPage] = ext_and_packaged;
- map[keys::kSidebar] = ext_and_packaged;
- map[keys::kHomepageURL] = ext_and_packaged;
-
- // Extensions, packaged apps and platform apps.
- int local_apps_and_ext = ext_and_packaged | Manifest::kTypePlatformApp;
- map[keys::kContentSecurityPolicy] = local_apps_and_ext;
- map[keys::kFileBrowserHandlers] = local_apps_and_ext;
- map[keys::kIncognito] = local_apps_and_ext;
- map[keys::kInputComponents] = local_apps_and_ext;
- map[keys::kTtsEngine] = local_apps_and_ext;
- map[keys::kIntents] = local_apps_and_ext;
- }
-
- // Returns true if the |key| is recognized.
- bool IsKnownKey(const std::string& key) const {
- RestrictionMap::const_iterator i = map.find(key);
- return i != map.end();
- }
-
- // Returns true if the given |key| can be specified by the manifest |type|.
- bool CanAccessKey(const std::string& key, Manifest::Type type) const {
- RestrictionMap::const_iterator i = map.find(key);
- return (i != map.end() && (type & i->second) != 0);
- }
-
- RestrictionMap map;
-};
-
-base::LazyInstance<Restrictions> g_restrictions;
-
-} // namespace
-
-// static
-std::set<std::string> Manifest::GetAllKnownKeys() {
- std::set<std::string> keys;
- const RestrictionMap& map = g_restrictions.Get().map;
- for (RestrictionMap::const_iterator i = map.begin(); i != map.end(); i++)
- keys.insert(i->first);
- return keys;
-}
-
-Manifest::Manifest(DictionaryValue* value) : value_(value) {}
-Manifest::~Manifest() {}
-
-bool Manifest::ValidateManifest(std::string* error) const {
- Restrictions restrictions = g_restrictions.Get();
- Type type = GetType();
-
- for (DictionaryValue::key_iterator key = value_->begin_keys();
- key != value_->end_keys(); ++key) {
- // When validating the extension manifests, we ignore keys that are not
- // recognized for forward compatibility.
- if (!restrictions.IsKnownKey(*key)) {
- // TODO(aa): Consider having an error here in the case of strict error
- // checking to let developers know when they screw up.
- continue;
- }
-
- if (!restrictions.CanAccessKey(*key, type)) {
- *error = ExtensionErrorUtils::FormatErrorMessage(
- errors::kFeatureNotAllowed, *key);
- return false;
- }
- }
-
- return true;
-}
-
-bool Manifest::HasKey(const std::string& key) const {
- Restrictions restrictions = g_restrictions.Get();
- return restrictions.CanAccessKey(key, GetType()) && value_->HasKey(key);
-}
-
-bool Manifest::Get(
- const std::string& path, Value** out_value) const {
- return CanAccessPath(path) && value_->Get(path, out_value);
-}
-
-bool Manifest::GetBoolean(
- const std::string& path, bool* out_value) const {
- return CanAccessPath(path) && value_->GetBoolean(path, out_value);
-}
-
-bool Manifest::GetInteger(
- const std::string& path, int* out_value) const {
- return CanAccessPath(path) && value_->GetInteger(path, out_value);
-}
-
-bool Manifest::GetString(
- const std::string& path, std::string* out_value) const {
- return CanAccessPath(path) && value_->GetString(path, out_value);
-}
-
-bool Manifest::GetString(
- const std::string& path, string16* out_value) const {
- return CanAccessPath(path) && value_->GetString(path, out_value);
-}
-
-bool Manifest::GetDictionary(
- const std::string& path, DictionaryValue** out_value) const {
- return CanAccessPath(path) && value_->GetDictionary(path, out_value);
-}
-
-bool Manifest::GetList(
- const std::string& path, ListValue** out_value) const {
- return CanAccessPath(path) && value_->GetList(path, out_value);
-}
-
-Manifest* Manifest::DeepCopy() const {
- return new Manifest(value_->DeepCopy());
-}
-
-bool Manifest::Equals(const Manifest* other) const {
- return other && value_->Equals(other->value());
-}
-
-Manifest::Type Manifest::GetType() const {
- if (value_->HasKey(keys::kTheme))
- return kTypeTheme;
- bool is_platform_app = false;
- if (value_->GetBoolean(keys::kPlatformApp, &is_platform_app) &&
- is_platform_app)
- return kTypePlatformApp;
- if (value_->HasKey(keys::kApp)) {
- if (value_->Get(keys::kWebURLs, NULL) ||
- value_->Get(keys::kLaunchWebURL, NULL))
- return kTypeHostedApp;
- else
- return kTypePackagedApp;
- } else {
- return kTypeExtension;
- }
-}
-
-bool Manifest::IsTheme() const {
- return GetType() == kTypeTheme;
-}
-
-bool Manifest::IsPlatformApp() const {
- return GetType() == kTypePlatformApp;
-}
-
-bool Manifest::IsPackagedApp() const {
- return GetType() == kTypePackagedApp;
-}
-
-bool Manifest::IsHostedApp() const {
- return GetType() == kTypeHostedApp;
-}
-
-bool Manifest::CanAccessPath(const std::string& path) const {
- std::vector<std::string> components;
- base::SplitString(path, '.', &components);
-
- Restrictions restrictions = g_restrictions.Get();
- return restrictions.CanAccessKey(components[0], GetType());
-}
-
-} // namespace extensions
diff --git a/chrome/common/extensions/manifest.h b/chrome/common/extensions/manifest.h
deleted file mode 100644
index fb372708..0000000
--- a/chrome/common/extensions/manifest.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_COMMON_EXTENSIONS_MANIFEST_H_
-#define CHROME_COMMON_EXTENSIONS_MANIFEST_H_
-#pragma once
-
-#include <map>
-#include <string>
-#include <set>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/string16.h"
-
-namespace base {
-class DictionaryValue;
-class ListValue;
-class Value;
-}
-
-namespace extensions {
-
-// Lightweight wrapper around a DictionaryValue representing an extension's
-// manifest. Currently enforces access to properties of the manifest based
-// on manifest type.
-//
-// TODO(aa): Move more smarts about mmanifest into this class over time.
-class Manifest {
- public:
- // Flags for matching types of extension manifests.
- enum Type {
- kTypeNone = 0,
-
- // Extension::TYPE_EXTENSION and Extension::TYPE_USER_SCRIPT
- kTypeExtension = 1 << 0,
-
- // Extension::TYPE_THEME
- kTypeTheme = 1 << 1,
-
- // Extension::TYPE_HOSTED_APP
- kTypeHostedApp = 1 << 2,
-
- // Extension::TYPE_PACKAGED_APP
- kTypePackagedApp = 1 << 3,
-
- // Extension::TYPE_PLATFORM_APP
- kTypePlatformApp = 1 << 4,
-
- // All types
- kTypeAll = (1 << 5) - 1,
- };
-
- // Returns all known keys (this is used for testing).
- static std::set<std::string> GetAllKnownKeys();
-
- // Takes over ownership of |value|.
- explicit Manifest(base::DictionaryValue* value);
- virtual ~Manifest();
-
- // Returns true if all keys in the manifest can be specified by
- // the extension type.
- bool ValidateManifest(std::string* error) const;
-
- // Returns the manifest type.
- Type GetType() const;
-
- // Returns true if the manifest represents an Extension::TYPE_THEME.
- bool IsTheme() const;
-
- // Returns true for Extension::TYPE_PLATFORM_APP
- bool IsPlatformApp() const;
-
- // Returns true for Extension::TYPE_PACKAGED_APP.
- bool IsPackagedApp() const;
-
- // Returns true for Extension::TYPE_HOSTED_APP.
- bool IsHostedApp() const;
-
- // These access the wrapped manifest value, returning false when the property
- // does not exist or if the manifest type can't access it.
- bool HasKey(const std::string& key) const;
- bool Get(const std::string& path, base::Value** out_value) const;
- bool GetBoolean(const std::string& path, bool* out_value) const;
- bool GetInteger(const std::string& path, int* out_value) const;
- bool GetString(const std::string& path, std::string* out_value) const;
- bool GetString(const std::string& path, string16* out_value) const;
- bool GetDictionary(const std::string& path,
- base::DictionaryValue** out_value) const;
- bool GetList(const std::string& path, base::ListValue** out_value) const;
-
- // Returns a new Manifest equal to this one, passing ownership to
- // the caller.
- Manifest* DeepCopy() const;
-
- // Returns true if this equals the |other| manifest.
- bool Equals(const Manifest* other) const;
-
- // Gets the underlying DictionaryValue representing the manifest.
- // Note: only know this when you KNOW you don't need the validation.
- base::DictionaryValue* value() const { return value_.get(); }
-
- private:
- // Returns true if the extension can specify the given |path|.
- bool CanAccessPath(const std::string& path) const;
-
- scoped_ptr<base::DictionaryValue> value_;
-};
-
-} // namespace extensions
-
-#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_H_
diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc
deleted file mode 100644
index 61282fa..0000000
--- a/chrome/common/extensions/manifest_unittest.cc
+++ /dev/null
@@ -1,392 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/common/extensions/manifest.h"
-
-#include <algorithm>
-#include <set>
-#include <string>
-
-#include "base/memory/scoped_ptr.h"
-#include "base/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/common/extensions/extension_error_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace keys = extension_manifest_keys;
-namespace errors = extension_manifest_errors;
-
-namespace extensions {
-
-namespace {
-
-// Keys that define types.
-const char* kTypeKeys[] = {
- keys::kApp,
- keys::kTheme,
- keys::kPlatformApp
-};
-
-// Keys that are not accesible by themes.
-const char* kNotThemeKeys[] = {
- keys::kBrowserAction,
- keys::kPageAction,
- keys::kPageActions,
- keys::kChromeURLOverrides,
- keys::kPermissions,
- keys::kOptionalPermissions,
- keys::kOptionsPage,
- keys::kBackground,
- keys::kOfflineEnabled,
- keys::kMinimumChromeVersion,
- keys::kRequirements,
- keys::kConvertedFromUserScript,
- keys::kNaClModules,
- keys::kPlugins,
- keys::kContentScripts,
- keys::kOmnibox,
- keys::kDevToolsPage,
- keys::kSidebar,
- keys::kHomepageURL,
- keys::kContentSecurityPolicy,
- keys::kFileBrowserHandlers,
- keys::kIncognito,
- keys::kInputComponents,
- keys::kTtsEngine,
- keys::kIntents
-};
-
-// Keys that are not accessible by hosted apps.
-const char* kNotHostedAppKeys[] = {
- keys::kBrowserAction,
- keys::kPageAction,
- keys::kPageActions,
- keys::kChromeURLOverrides,
- keys::kContentScripts,
- keys::kOmnibox,
- keys::kDevToolsPage,
- keys::kSidebar,
- keys::kHomepageURL,
- keys::kContentSecurityPolicy,
- keys::kFileBrowserHandlers,
- keys::kIncognito,
- keys::kInputComponents,
- keys::kTtsEngine,
- keys::kIntents
-};
-
-// Keys not accessible by packaged aps.
-const char* kNotPackagedAppKeys[] = {
- keys::kBrowserAction,
- keys::kPageAction,
- keys::kPageActions,
- keys::kChromeURLOverrides,
-};
-
-// Keys not accessible by platform apps.
-const char* kNotPlatformAppKeys[] = {
- keys::kBrowserAction,
- keys::kPageAction,
- keys::kPageActions,
- keys::kChromeURLOverrides,
- keys::kContentScripts,
- keys::kOmnibox,
- keys::kDevToolsPage,
- keys::kSidebar,
- keys::kHomepageURL,
-};
-
-// Returns all the manifest keys not including those in |filtered| or kTypeKeys.
-std::set<std::string> GetAccessibleKeys(const char* filtered[], size_t length) {
- std::set<std::string> all_keys = Manifest::GetAllKnownKeys();
- std::set<std::string> filtered_keys(filtered, filtered + length);
-
- // Starting with all possible manfiest keys, remove the keys that aren't
- // accessible for the given type.
- std::set<std::string> intermediate;
- std::set_difference(all_keys.begin(), all_keys.end(),
- filtered_keys.begin(), filtered_keys.end(),
- std::insert_iterator<std::set<std::string> >(
- intermediate, intermediate.begin()));
-
- // Then remove the keys that specify types (app, platform_app, etc.).
- std::set<std::string> result;
- std::set<std::string> type_keys(
- kTypeKeys, kTypeKeys + ARRAYSIZE_UNSAFE(kTypeKeys));
- std::set_difference(intermediate.begin(), intermediate.end(),
- type_keys.begin(), type_keys.end(),
- std::insert_iterator<std::set<std::string> >(
- result, result.begin()));
-
- return result;
-}
-
-} // namespace
-
-class ManifestTest : public testing::Test {
- public:
- ManifestTest() : default_value_("test") {}
-
- protected:
- void AssertType(Manifest* manifest, Manifest::Type type) {
- EXPECT_EQ(type, manifest->GetType());
- EXPECT_EQ(type == Manifest::kTypeTheme, manifest->IsTheme());
- EXPECT_EQ(type == Manifest::kTypePlatformApp, manifest->IsPlatformApp());
- EXPECT_EQ(type == Manifest::kTypePackagedApp, manifest->IsPackagedApp());
- EXPECT_EQ(type == Manifest::kTypeHostedApp, manifest->IsHostedApp());
- }
-
- void TestRestrictedKeys(Manifest* manifest,
- const char* restricted_keys[],
- size_t restricted_keys_length) {
- // Verify that the keys on the restricted key list for the given manifest
- // fail validation and are filtered out.
- DictionaryValue* value = manifest->value();
- for (size_t i = 0; i < restricted_keys_length; ++i) {
- std::string error, str;
- value->Set(restricted_keys[i], Value::CreateStringValue(default_value_));
- EXPECT_FALSE(manifest->ValidateManifest(&error));
- EXPECT_EQ(error, ExtensionErrorUtils::FormatErrorMessage(
- errors::kFeatureNotAllowed, restricted_keys[i]));
- EXPECT_FALSE(manifest->GetString(restricted_keys[i], &str));
- EXPECT_TRUE(value->Remove(restricted_keys[i], NULL));
- }
- }
-
- std::string default_value_;
-};
-
-// Verifies that extensions can access the correct keys.
-TEST_F(ManifestTest, Extension) {
- // Generate the list of keys accessible by extensions.
- std::set<std::string> extension_keys = GetAccessibleKeys(NULL, 0u);
-
- // Construct the underlying value using every single key other than those
- // on the restricted list.. We can use the same value for every key because we
- // validate only by checking the presence of the keys.
- DictionaryValue* value = new DictionaryValue();
- for (std::set<std::string>::iterator i = extension_keys.begin();
- i != extension_keys.end(); ++i)
- value->Set(*i, Value::CreateStringValue(default_value_));
-
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string error;
- EXPECT_TRUE(manifest->ValidateManifest(&error));
- EXPECT_EQ("", error);
- AssertType(manifest.get(), Manifest::kTypeExtension);
-
- // Verify that all the extension keys are accessible.
- for (std::set<std::string>::iterator i = extension_keys.begin();
- i != extension_keys.end(); ++i) {
- std::string value;
- manifest->GetString(*i, &value);
- EXPECT_EQ(default_value_, value) << *i;
- }
-
- // Test DeepCopy and Equals.
- scoped_ptr<Manifest> manifest2(manifest->DeepCopy());
- EXPECT_TRUE(manifest->Equals(manifest2.get()));
- EXPECT_TRUE(manifest2->Equals(manifest.get()));
- value->Set("foo", Value::CreateStringValue("blah"));
- EXPECT_FALSE(manifest->Equals(manifest2.get()));
-}
-
-// Verifies that themes can access the right keys.
-TEST_F(ManifestTest, Theme) {
- std::set<std::string> theme_keys =
- GetAccessibleKeys(kNotThemeKeys, ARRAYSIZE_UNSAFE(kNotThemeKeys));
-
- DictionaryValue* value = new DictionaryValue();
- for (std::set<std::string>::iterator i = theme_keys.begin();
- i != theme_keys.end(); ++i)
- value->Set(*i, Value::CreateStringValue(default_value_));
-
- std::string theme_key = keys::kTheme + std::string(".test");
- value->Set(theme_key, Value::CreateStringValue(default_value_));
-
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string error;
- EXPECT_TRUE(manifest->ValidateManifest(&error));
- EXPECT_EQ("", error);
- AssertType(manifest.get(), Manifest::kTypeTheme);
-
- // Verify that all the theme keys are accessible.
- std::string str;
- for (std::set<std::string>::iterator i = theme_keys.begin();
- i != theme_keys.end(); ++i) {
- EXPECT_TRUE(manifest->GetString(*i, &str));
- EXPECT_EQ(default_value_, str) << *i;
- }
- EXPECT_TRUE(manifest->GetString(theme_key, &str));
- EXPECT_EQ(default_value_, str) << theme_key;
-
- // And that all the other keys fail validation and are filtered out
- TestRestrictedKeys(manifest.get(), kNotThemeKeys,
- ARRAYSIZE_UNSAFE(kNotThemeKeys));
-};
-
-// Verifies that platform apps can access the right keys.
-TEST_F(ManifestTest, PlatformApp) {
- std::set<std::string> platform_keys = GetAccessibleKeys(
- kNotPlatformAppKeys,
- ARRAYSIZE_UNSAFE(kNotPlatformAppKeys));
-
- DictionaryValue* value = new DictionaryValue();
- for (std::set<std::string>::iterator i = platform_keys.begin();
- i != platform_keys.end(); ++i)
- value->Set(*i, Value::CreateStringValue(default_value_));
-
- value->Set(keys::kPlatformApp, Value::CreateBooleanValue(true));
-
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string error;
- EXPECT_TRUE(manifest->ValidateManifest(&error));
- EXPECT_EQ("", error);
- AssertType(manifest.get(), Manifest::kTypePlatformApp);
-
- // Verify that all the platform app keys are accessible.
- std::string str;
- for (std::set<std::string>::iterator i = platform_keys.begin();
- i != platform_keys.end(); ++i) {
- EXPECT_TRUE(manifest->GetString(*i, &str));
- EXPECT_EQ(default_value_, str) << *i;
- }
- bool is_platform_app = false;
- EXPECT_TRUE(manifest->GetBoolean(keys::kPlatformApp, &is_platform_app));
- EXPECT_TRUE(is_platform_app) << keys::kPlatformApp;
-
- // And that all the other keys fail validation and are filtered out.
- TestRestrictedKeys(manifest.get(), kNotPlatformAppKeys,
- ARRAYSIZE_UNSAFE(kNotPlatformAppKeys));
-};
-
-// Verifies that hosted apps can access the right keys.
-TEST_F(ManifestTest, HostedApp) {
- std::set<std::string> keys = GetAccessibleKeys(
- kNotHostedAppKeys,
- ARRAYSIZE_UNSAFE(kNotHostedAppKeys));
-
- DictionaryValue* value = new DictionaryValue();
- for (std::set<std::string>::iterator i = keys.begin();
- i != keys.end(); ++i)
- value->Set(*i, Value::CreateStringValue(default_value_));
-
- value->Set(keys::kWebURLs, Value::CreateStringValue(default_value_));
-
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string error;
- EXPECT_TRUE(manifest->ValidateManifest(&error));
- EXPECT_EQ("", error);
- AssertType(manifest.get(), Manifest::kTypeHostedApp);
-
- // Verify that all the hosted app keys are accessible.
- std::string str;
- for (std::set<std::string>::iterator i = keys.begin();
- i != keys.end(); ++i) {
- EXPECT_TRUE(manifest->GetString(*i, &str));
- EXPECT_EQ(default_value_, str) << *i;
- }
- EXPECT_TRUE(manifest->GetString(keys::kWebURLs, &str));
- EXPECT_EQ(default_value_, str) << keys::kWebURLs;
-
- // And that all the other keys fail validation and are filtered out.
- TestRestrictedKeys(manifest.get(), kNotHostedAppKeys,
- ARRAYSIZE_UNSAFE(kNotHostedAppKeys));
-};
-
-// Verifies that packaged apps can access the right keys.
-TEST_F(ManifestTest, PackagedApp) {
- std::set<std::string> keys = GetAccessibleKeys(
- kNotPackagedAppKeys,
- ARRAYSIZE_UNSAFE(kNotPackagedAppKeys));
-
- DictionaryValue* value = new DictionaryValue();
- for (std::set<std::string>::iterator i = keys.begin();
- i != keys.end(); ++i)
- value->Set(*i, Value::CreateStringValue(default_value_));
- value->Set(keys::kApp, Value::CreateStringValue(default_value_));
-
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string error;
- EXPECT_TRUE(manifest->ValidateManifest(&error));
- EXPECT_EQ("", error);
- AssertType(manifest.get(), Manifest::kTypePackagedApp);
-
- // Verify that all the packaged app keys are accessible.
- std::string str;
- for (std::set<std::string>::iterator i = keys.begin();
- i != keys.end(); ++i) {
- EXPECT_TRUE(manifest->GetString(*i, &str));
- EXPECT_EQ(default_value_, str) << *i;
- }
- EXPECT_TRUE(manifest->GetString(keys::kApp, &str));
- EXPECT_EQ(default_value_, str) << keys::kApp;
-
- // And that all the other keys fail validation and are filtered out.
- TestRestrictedKeys(manifest.get(), kNotPackagedAppKeys,
- ARRAYSIZE_UNSAFE(kNotPackagedAppKeys));
-};
-
-// Verifies that the various getters filter unknown and restricted keys.
-TEST_F(ManifestTest, Getters) {
- DictionaryValue* value = new DictionaryValue();
- scoped_ptr<Manifest> manifest(new Manifest(value));
- std::string unknown_key = "asdfaskldjf";
-
- // Verify that the key filtering works for each of the getters.
- // Get and GetBoolean
- bool expected_bool = true, actual_bool = false;
- value->Set(unknown_key, Value::CreateBooleanValue(expected_bool));
- EXPECT_FALSE(manifest->HasKey(unknown_key));
- EXPECT_FALSE(manifest->GetBoolean(unknown_key, &actual_bool));
- EXPECT_FALSE(actual_bool);
- Value* actual_value = NULL;
- EXPECT_FALSE(manifest->Get(unknown_key, &actual_value));
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-
- // GetInteger
- int expected_int = 5, actual_int = 0;
- value->Set(unknown_key, Value::CreateIntegerValue(expected_int));
- EXPECT_FALSE(manifest->GetInteger(unknown_key, &actual_int));
- EXPECT_NE(expected_int, actual_int);
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-
- // GetString
- std::string expected_str = "hello", actual_str;
- value->Set(unknown_key, Value::CreateStringValue(expected_str));
- EXPECT_FALSE(manifest->GetString(unknown_key, &actual_str));
- EXPECT_NE(expected_str, actual_str);
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-
- // GetString (string16)
- string16 expected_str16(UTF8ToUTF16("hello")), actual_str16;
- value->Set(unknown_key, Value::CreateStringValue(expected_str16));
- EXPECT_FALSE(manifest->GetString(unknown_key, &actual_str16));
- EXPECT_NE(expected_str16, actual_str16);
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-
- // GetDictionary
- DictionaryValue* expected_dict = new DictionaryValue();
- DictionaryValue* actual_dict = NULL;
- expected_dict->Set("foo", Value::CreateStringValue("bar"));
- value->Set(unknown_key, expected_dict);
- EXPECT_FALSE(manifest->GetDictionary(unknown_key, &actual_dict));
- EXPECT_EQ(NULL, actual_dict);
- std::string path = unknown_key + ".foo";
- EXPECT_FALSE(manifest->GetString(path, &actual_str));
- EXPECT_NE("bar", actual_str);
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-
- // GetList
- ListValue* expected_list = new ListValue();
- ListValue* actual_list = NULL;
- expected_list->Append(Value::CreateStringValue("blah"));
- value->Set(unknown_key, expected_list);
- EXPECT_FALSE(manifest->GetList(unknown_key, &actual_list));
- EXPECT_EQ(NULL, actual_list);
- EXPECT_TRUE(value->Remove(unknown_key, NULL));
-}
-
-} // namespace extensions