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
parent 73dca1b6
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/test/base/ui_test_utils.h" #include "chrome/test/base/ui_test_utils.h"
#include "content/browser/tab_contents/tab_contents.h" #include "content/browser/tab_contents/tab_contents.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
...@@ -99,10 +98,10 @@ IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, IsInstalled) { ...@@ -99,10 +98,10 @@ IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, IsInstalled) {
scoped_ptr<DictionaryValue> app_details( scoped_ptr<DictionaryValue> app_details(
static_cast<DictionaryValue*>( static_cast<DictionaryValue*>(
base::JSONReader::Read(result, false /* allow trailing comma */))); base::JSONReader::Read(result, false /* allow trailing comma */)));
// extension->manifest() does not contain the id. // extension->manifest_value() does not contain the id.
app_details->Remove("id", NULL); app_details->Remove("id", NULL);
EXPECT_TRUE(app_details.get()); EXPECT_TRUE(app_details.get());
EXPECT_TRUE(app_details->Equals(extension->manifest()->value())); EXPECT_TRUE(app_details->Equals(extension->manifest_value()));
// Try to change app.isInstalled. Should silently fail, so // Try to change app.isInstalled. Should silently fail, so
// that isInstalled should have the initial value. // that isInstalled should have the initial value.
...@@ -178,8 +177,8 @@ IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, GetDetailsForFrame) { ...@@ -178,8 +177,8 @@ IN_PROC_BROWSER_TEST_F(ChromeAppAPITest, GetDetailsForFrame) {
scoped_ptr<DictionaryValue> app_details( scoped_ptr<DictionaryValue> app_details(
static_cast<DictionaryValue*>( static_cast<DictionaryValue*>(
base::JSONReader::Read(json, false /* allow trailing comma */))); base::JSONReader::Read(json, false /* allow trailing comma */)));
// extension->manifest() does not contain the id. // extension->manifest_value() does not contain the id.
app_details->Remove("id", NULL); app_details->Remove("id", NULL);
EXPECT_TRUE(app_details.get()); EXPECT_TRUE(app_details.get());
EXPECT_TRUE(app_details->Equals(extension->manifest()->value())); EXPECT_TRUE(app_details->Equals(extension->manifest_value()));
} }
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "chrome/browser/prefs/scoped_user_pref_update.h" #include "chrome/browser/prefs/scoped_user_pref_update.h"
#include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/url_pattern.h" #include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
...@@ -1107,7 +1106,7 @@ void ExtensionPrefs::OnExtensionInstalled( ...@@ -1107,7 +1106,7 @@ void ExtensionPrefs::OnExtensionInstalled(
// since it may change on disk. // since it may change on disk.
if (extension->location() != Extension::LOAD) { if (extension->location() != Extension::LOAD) {
extension_dict->Set(kPrefManifest, extension_dict->Set(kPrefManifest,
extension->manifest()->value()->DeepCopy()); extension->manifest_value()->DeepCopy());
} }
if (extension->is_app()) { if (extension->is_app()) {
...@@ -1197,10 +1196,10 @@ void ExtensionPrefs::UpdateManifest(const Extension* extension) { ...@@ -1197,10 +1196,10 @@ void ExtensionPrefs::UpdateManifest(const Extension* extension) {
DictionaryValue* old_manifest = NULL; DictionaryValue* old_manifest = NULL;
bool update_required = bool update_required =
!extension_dict->GetDictionary(kPrefManifest, &old_manifest) || !extension_dict->GetDictionary(kPrefManifest, &old_manifest) ||
!extension->manifest()->value()->Equals(old_manifest); !extension->manifest_value()->Equals(old_manifest);
if (update_required) { if (update_required) {
UpdateExtensionPref(extension->id(), kPrefManifest, UpdateExtensionPref(extension->id(), kPrefManifest,
extension->manifest()->value()->DeepCopy()); extension->manifest_value()->DeepCopy());
} }
} }
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h" #include "chrome/common/extensions/extension_file_util.h"
#include "chrome/common/extensions/extension_l10n_util.h" #include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/pref_names.h" #include "chrome/common/pref_names.h"
#include "content/public/browser/notification_service.h" #include "content/public/browser/notification_service.h"
#include "content/browser/user_metrics.h" #include "content/browser/user_metrics.h"
...@@ -142,7 +141,7 @@ void InstalledLoader::LoadAllExtensions() { ...@@ -142,7 +141,7 @@ void InstalledLoader::LoadAllExtensions() {
if (extension.get()) { if (extension.get()) {
extensions_info->at(i)->extension_manifest.reset( extensions_info->at(i)->extension_manifest.reset(
static_cast<DictionaryValue*>( static_cast<DictionaryValue*>(
extension->manifest()->value()->DeepCopy())); extension->manifest_value()->DeepCopy()));
should_write_prefs = true; should_write_prefs = true;
} }
} }
......
...@@ -138,8 +138,6 @@ ...@@ -138,8 +138,6 @@
'common/extensions/extension_unpacker.h', 'common/extensions/extension_unpacker.h',
'common/extensions/file_browser_handler.cc', 'common/extensions/file_browser_handler.cc',
'common/extensions/file_browser_handler.h', 'common/extensions/file_browser_handler.h',
'common/extensions/manifest.cc',
'common/extensions/manifest.h',
'common/extensions/update_manifest.cc', 'common/extensions/update_manifest.cc',
'common/extensions/update_manifest.h', 'common/extensions/update_manifest.h',
'common/extensions/url_pattern.cc', 'common/extensions/url_pattern.cc',
......
...@@ -1959,7 +1959,6 @@ ...@@ -1959,7 +1959,6 @@
'common/extensions/extension_test_util.cc', 'common/extensions/extension_test_util.cc',
'common/extensions/extension_unittest.cc', 'common/extensions/extension_unittest.cc',
'common/extensions/extension_unpacker_unittest.cc', 'common/extensions/extension_unpacker_unittest.cc',
'common/extensions/manifest_unittest.cc',
'common/extensions/update_manifest_unittest.cc', 'common/extensions/update_manifest_unittest.cc',
'common/extensions/url_pattern_set_unittest.cc', 'common/extensions/url_pattern_set_unittest.cc',
'common/extensions/url_pattern_unittest.cc', 'common/extensions/url_pattern_unittest.cc',
......
This diff is collapsed.
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_icon_set.h" #include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_permission_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/user_script.h"
#include "chrome/common/extensions/url_pattern.h" #include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/extensions/url_pattern_set.h" #include "chrome/common/extensions/url_pattern_set.h"
...@@ -375,7 +374,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -375,7 +374,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// Parses the host and api permissions from the specified permission |key| // Parses the host and api permissions from the specified permission |key|
// in the manifest |source|. // in the manifest |source|.
bool ParsePermissions(const extensions::Manifest* source, bool ParsePermissions(const base::DictionaryValue* source,
const char* key, const char* key,
int flags, int flags,
std::string* error, std::string* error,
...@@ -532,8 +531,8 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -532,8 +531,8 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
} }
const GURL& update_url() const { return update_url_; } const GURL& update_url() const { return update_url_; }
const ExtensionIconSet& icons() const { return icons_; } const ExtensionIconSet& icons() const { return icons_; }
const extensions::Manifest* manifest() const { const base::DictionaryValue* manifest_value() const {
return manifest_.get(); return manifest_value_.get();
} }
const std::string default_locale() const { return default_locale_; } const std::string default_locale() const { return default_locale_; }
const URLOverrideMap& GetChromeURLOverrides() const { const URLOverrideMap& GetChromeURLOverrides() const {
...@@ -558,12 +557,12 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -558,12 +557,12 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
} }
// App-related. // App-related.
bool is_app() const { bool is_app() const { return is_app_; }
return is_packaged_app() || is_hosted_app() || is_platform_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_; } bool is_storage_isolated() const { return is_app() && is_storage_isolated_; }
const URLPatternSet& web_extent() const { return extent_; } const URLPatternSet& web_extent() const { return extent_; }
const std::string& launch_local_path() const { return launch_local_path_; } const std::string& launch_local_path() const { return launch_local_path_; }
...@@ -575,7 +574,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -575,7 +574,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
int launch_height() const { return launch_height_; } int launch_height() const { return launch_height_; }
// Theme-related. // 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* GetThemeImages() const { return theme_images_.get(); }
base::DictionaryValue* GetThemeColors() const {return theme_colors_.get(); } base::DictionaryValue* GetThemeColors() const {return theme_colors_.get(); }
base::DictionaryValue* GetThemeTints() const { return theme_tints_.get(); } base::DictionaryValue* GetThemeTints() const { return theme_tints_.get(); }
...@@ -617,8 +616,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -617,8 +616,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
~Extension(); ~Extension();
// Initialize the extension from a parsed manifest. // Initialize the extension from a parsed manifest.
// Takes ownership of the manifest |value|. bool InitFromValue(const base::DictionaryValue& value, int flags,
bool InitFromValue(extensions::Manifest* value, int flags,
std::string* error); std::string* error);
// Helper function for implementing HasCachedImage/GetCachedImage. A return // Helper function for implementing HasCachedImage/GetCachedImage. A return
...@@ -645,21 +643,24 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -645,21 +643,24 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
UserScript *instance); UserScript *instance);
// Helpers to load various chunks of the manifest. // 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, const char* key,
URLPatternSet* extent, URLPatternSet* extent,
const char* list_error, const char* list_error,
const char* value_error, const char* value_error,
URLPattern::ParseOption parse_strictness, URLPattern::ParseOption parse_strictness,
std::string* error); std::string* error);
bool LoadLaunchContainer(const extensions::Manifest* manifest, bool LoadLaunchContainer(const base::DictionaryValue* manifest,
std::string* error); std::string* error);
bool LoadLaunchURL(const extensions::Manifest* manifest, bool LoadLaunchURL(const base::DictionaryValue* manifest,
std::string* error); std::string* error);
bool LoadAppIsolation(const extensions::Manifest* manifest, bool LoadAppIsolation(const base::DictionaryValue* manifest,
std::string* error); std::string* error);
bool LoadWebIntentServices(const extensions::Manifest* manifest, bool LoadWebIntentServices(const base::DictionaryValue& manifest,
std::string* error); std::string* error);
bool EnsureNotHybridApp(const base::DictionaryValue* manifest,
std::string* error);
// Helper method to load an ExtensionAction from the page_action or // Helper method to load an ExtensionAction from the page_action or
// browser_action entries in the manifest. // browser_action entries in the manifest.
...@@ -682,6 +683,10 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -682,6 +683,10 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// an extension that has a browser action and a page action. // an extension that has a browser action and a page action.
bool HasMultipleUISurfaces() const; 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 // Updates the launch URL and extents for the extension using the given
// |override_url|. // |override_url|.
void OverrideLaunchUrl(const GURL& override_url); void OverrideLaunchUrl(const GURL& override_url);
...@@ -815,6 +820,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -815,6 +820,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// A map of display properties. // A map of display properties.
scoped_ptr<base::DictionaryValue> theme_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 // The homepage for this extension. Useful if it is not hosted by Google and
// therefore does not have a Gallery URL. // therefore does not have a Gallery URL.
GURL homepage_url_; GURL homepage_url_;
...@@ -822,13 +830,19 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -822,13 +830,19 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// URL for fetching an update manifest // URL for fetching an update manifest
GURL update_url_; GURL update_url_;
// The manifest that this extension was created from. // A copy of the manifest that this extension was created from.
scoped_ptr<extensions::Manifest> manifest_; scoped_ptr<base::DictionaryValue> manifest_value_;
// A map of chrome:// hostnames (newtab, downloads, etc.) to Extension URLs // A map of chrome:// hostnames (newtab, downloads, etc.) to Extension URLs
// which override the handling of those URLs. (see ExtensionOverrideUI). // which override the handling of those URLs. (see ExtensionOverrideUI).
URLOverrideMap chrome_url_overrides_; 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. // Whether this extension requests isolated storage.
bool is_storage_isolated_; bool is_storage_isolated_;
......
...@@ -166,8 +166,8 @@ const char kExpectString[] = "Expect string value."; ...@@ -166,8 +166,8 @@ const char kExpectString[] = "Expect string value.";
const char kExperimentalFlagRequired[] = const char kExperimentalFlagRequired[] =
"Loading extensions with 'experimental' permission requires" "Loading extensions with 'experimental' permission requires"
" --enable-experimental-extension-apis command line flag."; " --enable-experimental-extension-apis command line flag.";
const char kFeatureNotAllowed[] = const char kHostedAppsCannotIncludeExtensionFeatures[] =
"Feature '*' is not allowed in this type of manifest."; "Hosted apps cannot use the extension feature '*'.";
const char kInvalidAllFrames[] = const char kInvalidAllFrames[] =
"Invalid value for 'content_scripts[*].all_frames'."; "Invalid value for 'content_scripts[*].all_frames'.";
const char kInvalidBackground[] = const char kInvalidBackground[] =
...@@ -429,6 +429,8 @@ const char kReservedMessageFound[] = ...@@ -429,6 +429,8 @@ const char kReservedMessageFound[] =
const char kSidebarExperimental[] = const char kSidebarExperimental[] =
"You must request the 'experimental' permission in order to use the" "You must request the 'experimental' permission in order to use the"
" Sidebar API."; " Sidebar API.";
const char kThemesCannotContainExtensions[] =
"A theme cannot contain extensions code.";
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
const char kIllegalPlugins[] = const char kIllegalPlugins[] =
"Extensions cannot install plugins on Chrome OS"; "Extensions cannot install plugins on Chrome OS";
......
...@@ -150,7 +150,7 @@ namespace extension_manifest_errors { ...@@ -150,7 +150,7 @@ namespace extension_manifest_errors {
extern const char kDisabledByPolicy[]; extern const char kDisabledByPolicy[];
extern const char kExperimentalFlagRequired[]; extern const char kExperimentalFlagRequired[];
extern const char kExpectString[]; extern const char kExpectString[];
extern const char kFeatureNotAllowed[]; extern const char kHostedAppsCannotIncludeExtensionFeatures[];
extern const char kInvalidAllFrames[]; extern const char kInvalidAllFrames[];
extern const char kInvalidBackground[]; extern const char kInvalidBackground[];
extern const char kInvalidBackgroundInHostedApp[]; extern const char kInvalidBackgroundInHostedApp[];
...@@ -280,6 +280,7 @@ namespace extension_manifest_errors { ...@@ -280,6 +280,7 @@ namespace extension_manifest_errors {
extern const char kOneUISurfaceOnly[]; extern const char kOneUISurfaceOnly[];
extern const char kReservedMessageFound[]; extern const char kReservedMessageFound[];
extern const char kSidebarExperimental[]; extern const char kSidebarExperimental[];
extern const char kThemesCannotContainExtensions[];
extern const char kWebContentMustBeEnabled[]; extern const char kWebContentMustBeEnabled[];
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
extern const char kIllegalPlugins[]; extern const char kIllegalPlugins[];
......
...@@ -588,8 +588,12 @@ TEST_F(ExtensionManifestTest, Sidebar) { ...@@ -588,8 +588,12 @@ TEST_F(ExtensionManifestTest, Sidebar) {
extension->sidebar_defaults()->default_page().spec()); extension->sidebar_defaults()->default_page().spec());
} }
TEST_F(ExtensionManifestTest, BackgroundPermission) { TEST_F(ExtensionManifestTest, DisallowHybridApps) {
LoadAndExpectError("background_permission.json", LoadAndExpectError("disallow_hybrid_1.json",
ExtensionErrorUtils::FormatErrorMessage(
errors::kHostedAppsCannotIncludeExtensionFeatures,
keys::kBrowserAction));
LoadAndExpectError("disallow_hybrid_2.json",
errors::kBackgroundPermissionNeeded); errors::kBackgroundPermissionNeeded);
} }
...@@ -738,7 +742,9 @@ TEST_F(ExtensionManifestTest, NormalizeIconPaths) { ...@@ -738,7 +742,9 @@ TEST_F(ExtensionManifestTest, NormalizeIconPaths) {
} }
TEST_F(ExtensionManifestTest, DisallowMultipleUISurfaces) { 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) { TEST_F(ExtensionManifestTest, ParseHomepageURLs) {
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_constants.h" #include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/manifest.h"
#include "content/public/common/common_param_traits.h" #include "content/public/common/common_param_traits.h"
ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params() ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params()
...@@ -50,11 +49,10 @@ ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params( ...@@ -50,11 +49,10 @@ ExtensionMsg_Loaded_Params::ExtensionMsg_Loaded_Params(
extension_manifest_keys::kVersion, extension_manifest_keys::kVersion,
}; };
// Copy only the data we need and bypass the manifest type checks. // Copy only the data we need.
DictionaryValue* source = extension->manifest()->value();
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRendererExtensionKeys); ++i) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRendererExtensionKeys); ++i) {
Value* temp = NULL; Value* temp = NULL;
if (source->Get(kRendererExtensionKeys[i], &temp)) if (extension->manifest_value()->Get(kRendererExtensionKeys[i], &temp))
manifest->Set(kRendererExtensionKeys[i], temp->DeepCopy()); manifest->Set(kRendererExtensionKeys[i], temp->DeepCopy());
} }
} }
......
// 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
// 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_
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/extension_set.h" #include "chrome/common/extensions/extension_set.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/renderer/extensions/chrome_v8_context.h" #include "chrome/renderer/extensions/chrome_v8_context.h"
#include "chrome/renderer/extensions/extension_dispatcher.h" #include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h" #include "chrome/renderer/extensions/extension_helper.h"
...@@ -195,7 +194,7 @@ v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl( ...@@ -195,7 +194,7 @@ v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl(
return v8::Null(); return v8::Null();
scoped_ptr<DictionaryValue> manifest_copy( scoped_ptr<DictionaryValue> manifest_copy(
extension->manifest()->value()->DeepCopy()); extension->manifest_value()->DeepCopy());
manifest_copy->SetString("id", extension->id()); manifest_copy->SetString("id", extension->id());
scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
return converter->ToV8Value(manifest_copy.get(), return converter->ToV8Value(manifest_copy.get(),
......
{
"name": "test",
"version": "1",
"app": {
"urls": [
"http://www.google.com/mail/",
"http://www.google.com/foobar/"
],
"launch": {
"web_url": "http://www.google.com/mail/"
}
},
"permissions": [
"notifications"
],
"browser_action": {}
}
{
"name": "foo",
"version": "1",
"browser_action": {},
"app": {
"launch": {
"local_path": "foo.html"
}
}
}
{
"name": "foo",
"version": "1",
"browser_action": {},
"page_action": {},
"app": {
"launch": {
"local_path": "foo.html"
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment