diff options
author | andybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-19 15:22:20 +0000 |
---|---|---|
committer | andybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-19 15:22:20 +0000 |
commit | 9bf14a24e1de759fddfbbee8050d65ef2d95ef18 (patch) | |
tree | 24aa03d05b22be52366d8baf06dab96638ecf71b /chrome/common/extensions | |
parent | e685fc4178818c026f1498461edb3f2bfeff5722 (diff) | |
download | chromium_src-9bf14a24e1de759fddfbbee8050d65ef2d95ef18.zip chromium_src-9bf14a24e1de759fddfbbee8050d65ef2d95ef18.tar.gz chromium_src-9bf14a24e1de759fddfbbee8050d65ef2d95ef18.tar.bz2 |
Revert 42091 - Refactor apprelated manifest properties so that they don't
include the name 'app'. I think these will be useful for normal
extensions, too.
Also extract an ExtensionExtent class out of Extension. I think
this will be useful for passing by value to the IO thread.
Review URL: http://codereview.chromium.org/1025006
TBR=aa@chromium.org
Review URL: http://codereview.chromium.org/1120005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42104 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/extensions')
-rw-r--r-- | chrome/common/extensions/extension.cc | 258 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 66 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 51 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 39 | ||||
-rw-r--r-- | chrome/common/extensions/extension_extent.cc | 28 | ||||
-rw-r--r-- | chrome/common/extensions/extension_extent.h | 34 | ||||
-rw-r--r-- | chrome/common/extensions/extension_extent_unittest.cc | 57 | ||||
-rw-r--r-- | chrome/common/extensions/extension_manifests_unittest.cc | 162 | ||||
-rw-r--r-- | chrome/common/extensions/extension_unittest.cc | 59 |
9 files changed, 189 insertions, 565 deletions
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 81e15d1..b12c764 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -488,185 +488,98 @@ bool Extension::ContainsNonThemeKeys(const DictionaryValue& source) { return false; } -bool Extension::CheckAppsAreEnabled(const DictionaryValue* manifest, - std::string* error) { - if (!apps_enabled_) { - if (manifest->HasKey(keys::kWebContent) || - manifest->HasKey(keys::kLaunch)) { - *error = errors::kAppsNotEnabled; - return false; - } - } - - return true; -} - -bool Extension::LoadWebContentEnabled(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (manifest->Get(keys::kWebContentEnabled, &temp)) { - if (!temp->GetAsBoolean(&web_content_enabled_)) { - *error = errors::kInvalidWebContentEnabled; - return false; - } - } - - // The enabled flag must be set to use the web_content dictionary at all. - if (!web_content_enabled_ && manifest->HasKey(keys::kWebContent)) { - *error = errors::kWebContentMustBeEnabled; - return false; - } - - return true; +// We're likely going to want to restrict apps away from certain APIs/features. +// TODO(erikkay) - figure out what APIs to block. +bool Extension::ContainsNonAppKeys(const DictionaryValue& source) { + return false; } -bool Extension::LoadWebOrigin(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kWebOrigin, &temp)) - return true; - - // Check datatype. - std::string origin_string; - if (!temp->GetAsString(&origin_string)) { - *error = errors::kInvalidWebOrigin; - return false; - } - - // Origin must be a valid URL. - GURL origin_gurl(origin_string); - if (!origin_gurl.is_valid() || origin_gurl.is_empty()) { - *error = errors::kInvalidWebOrigin; - return false; - } - - // Origins can only be http or https. - if (!origin_gurl.SchemeIs(chrome::kHttpScheme) && - !origin_gurl.SchemeIs(chrome::kHttpsScheme)) { - *error = errors::kInvalidWebOrigin; +bool Extension::LoadAppHelper(const DictionaryValue* app, std::string* error) { + // launch URL + std::string launch_url_spec; + if (!app->GetString(keys::kAppLaunchUrl, &launch_url_spec)) { + *error = errors::kInvalidAppLaunchUrl; return false; } - - // Check that the origin doesn't include any extraneous information. - if (origin_gurl.GetOrigin() != origin_gurl) { - *error = errors::kInvalidWebOrigin; - return false; - } - - web_extent_.set_origin(origin_gurl); - return true; -} - -bool Extension::LoadWebPaths(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kWebPaths, &temp)) - return true; - - // Check datatype. - if (!temp->IsType(Value::TYPE_LIST)) { - *error = errors::kInvalidWebPaths; + app_launch_url_ = GURL(launch_url_spec); + if (!app_launch_url_.is_valid()) { + *error = errors::kInvalidAppLaunchUrl; return false; } - ListValue* web_paths = static_cast<ListValue*>(temp); - for (size_t i = 0; i < web_paths->GetSize(); ++i) { - // Get item and check datatype. - std::string item; - if (!web_paths->GetString(i, &item) || item.empty()) { - *error = ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, IntToString(i)); - return false; - } - - // Ensure the path is a valid relative URL by resolving it against the - // extension root. - // TODO(aa): This is hacky. Is there another way to know whether a string - // is a valid relative URL? - GURL resolved = extension_url_.Resolve(item); - if (!resolved.is_valid() || resolved.GetOrigin() != extension_url_) { - *error = ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, IntToString(i)); + // launch type + app_launch_type_ = LAUNCH_WINDOW; // TODO(erikkay) LAUNCH_TAB? + std::string launch_type_string; + if (app->GetString(keys::kAppLaunchType, &launch_type_string)) { + if (launch_type_string == std::string(values::kLaunchTypePanel)) { + app_launch_type_ = LAUNCH_PANEL; + } else if (launch_type_string == std::string(values::kLaunchTypeTab)) { + app_launch_type_ = LAUNCH_TAB; + } else if (launch_type_string != std::string(values::kLaunchTypeWindow)) { + *error = errors::kInvalidAppLaunchType; return false; } - - web_extent_.add_path(item); } - return true; -} + // The launch URL is automatically added to the extent. + URLPattern pattern; + pattern.set_scheme(app_launch_url_.scheme()); + pattern.set_host(app_launch_url_.host()); + pattern.set_path(app_launch_url_.path()); + app_extent_.push_back(pattern); -bool Extension::LoadLaunchURL(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - - // launch URL can be either local (to chrome-extension:// root) or web (either - // relative to the origin, or an absolute URL). - if (manifest->Get(keys::kLaunchLocalPath, &temp)) { - if (manifest->Get(keys::kLaunchWebURL, NULL)) { - *error = errors::kLaunchPathAndURLAreExclusive; + // extent + if (app->HasKey(keys::kAppExtent)) { + ListValue* extent; + if (!app->GetList(keys::kAppExtent, &extent)) { + *error = errors::kInvalidAppExtent; return false; } + for (ListValue::const_iterator iter = extent->begin(); + iter != extent->end(); ++iter) { + std::string item; + if (!(*iter)->GetAsString(&item) || item.empty()) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidAppExtentPattern, item); + return false; + } + if (!pattern.Parse(item)) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidAppExtentPattern, item); + return false; + } + app_extent_.push_back(pattern); + } + } - std::string launch_path; - if (!temp->GetAsString(&launch_path)) { - *error = errors::kInvalidLaunchLocalPath; + if (app->HasKey(keys::kAppOrigin)) { + std::string origin_string; + if (!app->GetString(keys::kAppOrigin, &origin_string)) { + *error = errors::kInvalidAppOrigin; return false; } - // Ensure the launch path is a valid relative URL. - GURL resolved = extension_url_.Resolve(launch_path); - if (!resolved.is_valid() || resolved.GetOrigin() != extension_url_) { - *error = errors::kInvalidLaunchLocalPath; + // Origin must be a valid URL. + GURL origin_gurl(origin_string); + if (!origin_gurl.is_valid() || origin_gurl.is_empty()) { + *error = errors::kInvalidAppOrigin; return false; } - launch_local_path_ = launch_path; - } else if (manifest->Get(keys::kLaunchWebURL, &temp)) { - std::string launch_url; - if (!temp->GetAsString(&launch_url)) { - *error = errors::kInvalidLaunchWebURL; + // Origins can only be http or https. + if (!origin_gurl.SchemeIs(chrome::kHttpScheme) && + !origin_gurl.SchemeIs(chrome::kHttpsScheme)) { + *error = errors::kInvalidAppOrigin; return false; } - // Ensure the launch URL is a valid relative or absolute URL. - if (!extension_url_.Resolve(launch_url).is_valid()) { - *error = errors::kInvalidLaunchWebURL; + // Check that the origin doesn't include any extraneous information. + if (origin_gurl.GetOrigin() != origin_gurl) { + *error = errors::kInvalidAppOrigin; return false; } - launch_web_url_ = launch_url; - } - - return true; -} - -bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kLaunchContainer, &temp)) - return true; - - std::string launch_container_string; - if (!temp->GetAsString(&launch_container_string)) { - *error = errors::kInvalidLaunchContainer; - return false; - } - - if (launch_local_path_.empty() && launch_web_url_.empty()) { - *error = errors::kLaunchContainerWithoutURL; - return false; - } - - if (launch_container_string == values::kLaunchContainerPanel) { - launch_container_ = LAUNCH_PANEL; - } else if (launch_container_string == values::kLaunchContainerTab) { - launch_container_ = LAUNCH_TAB; - } else if (launch_container_string == values::kLaunchContainerWindow) { - launch_container_ = LAUNCH_WINDOW; - } else { - *error = errors::kInvalidLaunchContainer; - return false; + app_origin_ = origin_gurl; } return true; @@ -675,14 +588,9 @@ bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, Extension::Extension(const FilePath& path) : converted_from_user_script_(false), is_theme_(false), - web_content_enabled_(false), - launch_container_(LAUNCH_TAB), background_page_ready_(false), being_upgraded_(false) { DCHECK(path.IsAbsolute()); - - apps_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExtensionApps); location_ = INVALID; #if defined(OS_WIN) @@ -1385,13 +1293,20 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, } } - if (!CheckAppsAreEnabled(manifest_value_.get(), error) || - !LoadWebContentEnabled(manifest_value_.get(), error) || - !LoadWebOrigin(manifest_value_.get(), error) || - !LoadWebPaths(manifest_value_.get(), error) || - !LoadLaunchURL(manifest_value_.get(), error) || - !LoadLaunchContainer(manifest_value_.get(), error)) { - return false; + // If it's an app, load the appropriate keys, etc. + if (source.HasKey(keys::kApp)) { + if (ContainsNonAppKeys(source)) { + *error = errors::kInvalidApp; + return false; + } + DictionaryValue* app; + if (!source.GetDictionary(keys::kApp, &app)) { + *error = errors::kInvalidApp; + return false; + } + if (!LoadAppHelper(app, error)) { + return false; + } } // Although |source| is passed in as a const, it's still possible to modify @@ -1445,21 +1360,6 @@ std::set<FilePath> Extension::GetBrowserImages() { return image_paths; } -GURL Extension::GetFullLaunchURL() const { - if (!launch_local_path_.empty()) { - return extension_url_.Resolve(launch_local_path_); - } else if (!launch_web_url_.empty()) { - // If there is a web origin, we interpret the launch URL relatively to that. - // Otherwise, hopefully it was an absolute URL. - if (web_extent_.origin().is_valid()) - return web_extent_.origin().Resolve(launch_web_url_); - else - return GURL(launch_web_url_); - } else { - return GURL(); - } -} - bool Extension::GetBackgroundPageReady() { return background_page_ready_ || background_url().is_empty(); } diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 418a01a..50fe957 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -15,7 +15,6 @@ #include "base/values.h" #include "base/version.h" #include "chrome/common/extensions/extension_action.h" -#include "chrome/common/extensions/extension_extent.h" #include "chrome/common/extensions/extension_resource.h" #include "chrome/common/extensions/user_script.h" #include "chrome/common/extensions/url_pattern.h" @@ -68,15 +67,12 @@ class Extension { EXTENSION_ICON_BITTY = 16, }; - enum LaunchContainer { + enum AppLaunchType { LAUNCH_WINDOW, LAUNCH_PANEL, LAUNCH_TAB }; - bool apps_enabled() const { return apps_enabled_; } - void set_apps_enabled(bool val) { apps_enabled_ = val; } - // Icon sizes used by the extension system. static const int kIconSizes[]; @@ -292,15 +288,12 @@ class Extension { return chrome_url_overrides_; } - bool web_content_enabled() const { return web_content_enabled_; } - const ExtensionExtent& web_extent() const { return web_extent_; } - - const std::string& launch_local_path() const { return launch_local_path_; } - const std::string& launch_web_url() const { return launch_web_url_; } - const LaunchContainer launch_container() const { return launch_container_; } - - // Gets the fully resolved absolute launch URL. - GURL GetFullLaunchURL() const; + // App stuff. + const URLPatternList& app_extent() const { return app_extent_; } + const GURL& app_launch_url() const { return app_launch_url_; } + bool IsApp() const { return !app_launch_url_.is_empty(); } + AppLaunchType app_launch_type() { return app_launch_type_; } + const GURL& app_origin() const { return app_origin_; } // Runtime data: // Put dynamic data about the state of a running extension below. @@ -333,18 +326,6 @@ class Extension { void(UserScript::*add_method)(const std::string& glob), UserScript *instance); - // Checks that apps features are enabled if the manifest tries to use any of - // them. - bool CheckAppsAreEnabled(const DictionaryValue* manifest, std::string* error); - - // Helpers to load various chunks of the manifest. - bool LoadWebContentEnabled(const DictionaryValue* manifest, - std::string* error); - bool LoadWebOrigin(const DictionaryValue* manifest, std::string* error); - bool LoadWebPaths(const DictionaryValue* manifest, std::string* error); - bool LoadLaunchContainer(const DictionaryValue* manifest, std::string* error); - bool LoadLaunchURL(const DictionaryValue* manifest, std::string* error); - // Helper method to load an ExtensionAction from the page_action or // browser_action entries in the manifest. ExtensionAction* LoadExtensionActionHelper( @@ -354,6 +335,13 @@ class Extension { // don't want to allow scripts and such to be bundled with themes. bool ContainsNonThemeKeys(const DictionaryValue& source); + // Apps don't have access to all extension features. This enforces those + // restrictions. + bool ContainsNonAppKeys(const DictionaryValue& source); + + // Helper method to verify the app section of the manifest. + bool LoadAppHelper(const DictionaryValue* app, std::string* error); + // Returns true if the string is one of the known api permissions (see // kPermissionNames). bool IsAPIPermission(const std::string& permission); @@ -451,26 +439,18 @@ class Extension { // which override the handling of those URLs. URLOverrideMap chrome_url_overrides_; - // Whether apps-related features can be parsed during InitFromValue(). - // Defaults to the value from --enable-extension-apps. - bool apps_enabled_; - - // Whether the extension can contain live web content. Defaults to false. - bool web_content_enabled_; - - // Defines the set of URLs in the extension's web content. - ExtensionExtent web_extent_; - - // The local path inside the extension to use with the launcher. - std::string launch_local_path_; + // Describes the space of URLs that are displayed in the app's custom frame. + URLPatternList app_extent_; - // A web url to use with the launcher. Note that this might be relative or - // absolute. If relative, it is relative to web_origin_. - std::string launch_web_url_; + // The URL an app should launch to. + GURL app_launch_url_; - // The type of container to launch into. - LaunchContainer launch_container_; + // How to start when the application is launched. + AppLaunchType app_launch_type_; + // The web security origin associated with the app. This origin will be + // granted the permissions the app requests. + GURL app_origin_; // Runtime data: diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index f28fad1..1c9c5c9 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -7,6 +7,11 @@ namespace extension_manifest_keys { const wchar_t* kAllFrames = L"all_frames"; +const wchar_t* kApp = L"app"; +const wchar_t* kAppExtent = L"extent"; +const wchar_t* kAppLaunchUrl = L"launch.url"; +const wchar_t* kAppLaunchType = L"launch.window_type"; // TODO(erikkay) rename +const wchar_t* kAppOrigin = L"origin"; const wchar_t* kBackground = L"background_page"; const wchar_t* kBrowserAction = L"browser_action"; const wchar_t* kChromeURLOverrides = L"chrome_url_overrides"; @@ -18,10 +23,6 @@ const wchar_t* kDefaultLocale = L"default_locale"; const wchar_t* kDescription = L"description"; const wchar_t* kIcons = L"icons"; const wchar_t* kJs = L"js"; -const wchar_t* kLaunch = L"launch"; -const wchar_t* kLaunchContainer = L"launch.container"; -const wchar_t* kLaunchLocalPath = L"launch.local_path"; -const wchar_t* kLaunchWebURL = L"launch.web_url"; const wchar_t* kMatches = L"matches"; const wchar_t* kMinimumChromeVersion = L"minimum_chrome_version"; const wchar_t* kIncludeGlobs = L"include_globs"; @@ -57,10 +58,6 @@ const wchar_t* kType = L"type"; const wchar_t* kVersion = L"version"; const wchar_t* kUpdateURL = L"update_url"; const wchar_t* kOptionsPage = L"options_page"; -const wchar_t* kWebContent = L"web_content"; -const wchar_t* kWebContentEnabled = L"web_content.enabled"; -const wchar_t* kWebOrigin = L"web_content.origin"; -const wchar_t* kWebPaths = L"web_content.paths"; } // namespace extension_manifest_keys namespace extension_manifest_values { @@ -69,9 +66,9 @@ const char* kRunAtDocumentEnd = "document_end"; const char* kRunAtDocumentIdle = "document_idle"; const char* kPageActionTypeTab = "tab"; const char* kPageActionTypePermanent = "permanent"; -const char* kLaunchContainerPanel = "panel"; -const char* kLaunchContainerTab = "tab"; -const char* kLaunchContainerWindow = "window"; +const char* kLaunchTypePanel = "panel"; +const char* kLaunchTypeTab = "tab"; +const char* kLaunchTypeWindow = "window"; } // namespace extension_manifest_values // Extension-related error messages. Some of these are simple patterns, where a @@ -79,11 +76,21 @@ const char* kLaunchContainerWindow = "window"; // printf because we want to unit test them and scanf is hard to make // cross-platform. namespace extension_manifest_errors { -const char* kAppsNotEnabled = "Apps are not enabled."; +const char* kAppsDisabled = "Apps are disabled."; const char* kChromeVersionTooLow = "This extension requires * version * or greater."; const char* kInvalidAllFrames = "Invalid value for 'content_scripts[*].all_frames'."; +const char* kInvalidApp = "Invalid app."; +const char* kInvalidAppExtent = "Invalid value for app.extent."; +const char* kInvalidAppExtentPattern = "Invalid value for app.extent[*]."; +const char* kInvalidAppLaunchType = + "Invalid value for 'app.launch.window_type'."; +const char* kInvalidAppLaunchUrl = + "Required value 'app.launch.url' is missing or invalid."; +const char* kInvalidAppOrigin = + "Invalid value for 'app.origin'. Value must be a URL of the form " + "scheme://host[:port]/ where scheme is http or https."; const char* kInvalidBrowserAction = "Invalid value for 'browser_action'."; const char* kInvalidChromeURLOverrides = @@ -110,12 +117,6 @@ const char* kInvalidJs = "Invalid value for 'content_scripts[*].js[*]'."; const char* kInvalidJsList = "Required value 'content_scripts[*].js' is invalid."; -const char* kInvalidLaunchContainer = - "Invalid value for 'launch.container'."; -const char* kInvalidLaunchLocalPath = - "Invalid value for 'launch.local_path'."; -const char* kInvalidLaunchWebURL = - "Invalid value for 'launch.web_url'."; const char* kInvalidKey = "Value 'key' is missing or invalid."; const char* kInvalidManifest = @@ -202,24 +203,12 @@ const char* kInvalidThemeTints = "Invalid value for theme images - tints must be decimal numbers."; const char* kInvalidUpdateURL = "Invalid value for update url: '[*]'."; -const char* kInvalidWebContentEnabled = - "Invalid value for 'web_content.enabled'."; -const char* kInvalidWebOrigin = - "Invalid value for 'web_content.origin'."; -const char* kInvalidWebPaths = - "Invalid value for 'web_content.paths'."; -const char* kInvalidWebPath = - "Invalid value for 'web_contents.paths[*]'."; const char* kInvalidDefaultLocale = "Invalid value for default locale - locale name must be a string."; const char* kOneUISurfaceOnly = "An extension cannot have both a page action and a browser action."; const char* kThemesCannotContainExtensions = "A theme cannot contain extensions code."; -const char* kLaunchContainerWithoutURL = - "Launch container specified, but no local_path or web_url to launch."; -const char* kLaunchPathAndURLAreExclusive = - "The 'launch.local_path' and 'launch.web_url' keys cannot both be set."; const char* kLocalesNoDefaultLocaleSpecified = "Localization used, but default_locale wasn't specified in the manifest."; const char* kLocalesNoDefaultMessages = @@ -237,8 +226,6 @@ const char* kReservedMessageFound = const char* kCannotAccessPage = "Cannot access contents of url \"*\". " "Extension manifest must request permission to access this host."; const char* kCannotScriptGallery = "The extensions gallery cannot be scripted."; -const char* kWebContentMustBeEnabled = "The 'web_content.enabled' property " - "must be set to true in order to use any other web content features."; } // namespace extension_manifest_errors namespace extension_urls { diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index e3f1a0c..453fb1c 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -8,6 +8,11 @@ // Keys used in JSON representation of extensions. namespace extension_manifest_keys { extern const wchar_t* kAllFrames; + extern const wchar_t* kApp; + extern const wchar_t* kAppExtent; + extern const wchar_t* kAppLaunchUrl; + extern const wchar_t* kAppLaunchType; + extern const wchar_t* kAppOrigin; extern const wchar_t* kBackground; extern const wchar_t* kBrowserAction; extern const wchar_t* kMinimumChromeVersion; @@ -21,10 +26,6 @@ namespace extension_manifest_keys { extern const wchar_t* kExcludeGlobs; extern const wchar_t* kIcons; extern const wchar_t* kIncludeGlobs; - extern const wchar_t* kLaunch; - extern const wchar_t* kLaunchContainer; - extern const wchar_t* kLaunchLocalPath; - extern const wchar_t* kLaunchWebURL; extern const wchar_t* kJs; extern const wchar_t* kMatches; extern const wchar_t* kName; @@ -58,11 +59,6 @@ namespace extension_manifest_keys { extern const wchar_t* kVersion; extern const wchar_t* kUpdateURL; extern const wchar_t* kOptionsPage; - extern const wchar_t* kWebContent; - extern const wchar_t* kWebContentEnabled; - extern const wchar_t* kWebLaunchUrl; - extern const wchar_t* kWebOrigin; - extern const wchar_t* kWebPaths; } // namespace extension_manifest_keys // Some values expected in manifests. @@ -72,16 +68,22 @@ namespace extension_manifest_values { extern const char* kRunAtDocumentIdle; extern const char* kPageActionTypeTab; extern const char* kPageActionTypePermanent; - extern const char* kLaunchContainerPanel; - extern const char* kLaunchContainerTab; - extern const char* kLaunchContainerWindow; + extern const char* kLaunchTypePanel; + extern const char* kLaunchTypeTab; + extern const char* kLaunchTypeWindow; } // namespace extension_manifest_values // Error messages returned from Extension::InitFromValue(). namespace extension_manifest_errors { - extern const char* kAppsNotEnabled; + extern const char* kAppsDisabled; extern const char* kChromeVersionTooLow; extern const char* kInvalidAllFrames; + extern const char* kInvalidApp; + extern const char* kInvalidAppExtent; + extern const char* kInvalidAppExtentPattern; + extern const char* kInvalidAppLaunchType; + extern const char* kInvalidAppLaunchUrl; + extern const char* kInvalidAppOrigin; extern const char* kInvalidBackground; extern const char* kInvalidBrowserAction; extern const char* kInvalidChromeURLOverrides; @@ -97,9 +99,6 @@ namespace extension_manifest_errors { extern const char* kInvalidJs; extern const char* kInvalidJsList; extern const char* kInvalidKey; - extern const char* kInvalidLaunchContainer; - extern const char* kInvalidLaunchLocalPath; - extern const char* kInvalidLaunchWebURL; extern const char* kInvalidManifest; extern const char* kInvalidMatchCount; extern const char* kInvalidMatch; @@ -109,6 +108,7 @@ namespace extension_manifest_errors { extern const char* kInvalidPlugins; extern const char* kInvalidPluginsPath; extern const char* kInvalidPluginsPublic; + extern const char* kInvalidRunAt; extern const char* kInvalidSignature; extern const char* kInvalidToolstrip; @@ -135,10 +135,6 @@ namespace extension_manifest_errors { extern const char* kInvalidThemeImages; extern const char* kInvalidThemeColors; extern const char* kInvalidThemeTints; - extern const char* kInvalidWebContentEnabled; - extern const char* kInvalidWebOrigin; - extern const char* kInvalidWebPaths; - extern const char* kInvalidWebPath; extern const char* kOneUISurfaceOnly; extern const char* kThemesCannotContainExtensions; extern const char* kManifestParseError; @@ -146,8 +142,6 @@ namespace extension_manifest_errors { extern const char* kMissingFile; extern const char* kInvalidUpdateURL; extern const char* kInvalidDefaultLocale; - extern const char* kLaunchContainerWithoutURL; - extern const char* kLaunchPathAndURLAreExclusive; extern const char* kLocalesNoDefaultLocaleSpecified; extern const char* kLocalesNoDefaultMessages; extern const char* kLocalesNoValidLocaleNamesListed; @@ -157,7 +151,6 @@ namespace extension_manifest_errors { extern const char* kReservedMessageFound; extern const char* kCannotAccessPage; extern const char* kCannotScriptGallery; - extern const char* kWebContentMustBeEnabled; } // namespace extension_manifest_errors namespace extension_urls { diff --git a/chrome/common/extensions/extension_extent.cc b/chrome/common/extensions/extension_extent.cc deleted file mode 100644 index 310673e..0000000 --- a/chrome/common/extensions/extension_extent.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2010 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/extension_extent.h" - -#include "base/string_util.h" - -bool ExtensionExtent::ContainsURL(const GURL& url) { - if (!url.is_valid()) - return false; - - if (url.GetOrigin() != origin_) - return false; - - if (paths_.empty()) - return true; - - for (size_t i = 0; i < paths_.size(); ++i) { - if (StartsWithASCII(url.path(), - std::string("/") + paths_[i], - false)) { // not case sensitive - return true; - } - } - - return false; -} diff --git a/chrome/common/extensions/extension_extent.h b/chrome/common/extensions/extension_extent.h deleted file mode 100644 index 76670ab..0000000 --- a/chrome/common/extensions/extension_extent.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2010 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_EXTENSION_EXTENT_H_ -#define CHROME_COMMON_EXTENSIONS_EXTENSION_EXTENT_H_ - -#include <string> -#include <vector> - -#include "googleurl/src/gurl.h" - -// Represents the set of URLs an extension uses for web content. -class ExtensionExtent { - public: - const std::vector<std::string>& paths() const { return paths_; } - void add_path(const std::string& val) { paths_.push_back(val); } - void clear_paths() { paths_.clear(); } - - const GURL& origin() const { return origin_; } - void set_origin(const GURL& val) { origin_ = val; } - - bool ContainsURL(const GURL& url); - - private: - // The security origin (scheme+host+port) of the extent. - GURL origin_; - - // A set of path prefixes that further restrict the set of valid URLs below - // origin_. This may be empty. - std::vector<std::string> paths_; -}; - -#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_EXTENT_H_ diff --git a/chrome/common/extensions/extension_extent_unittest.cc b/chrome/common/extensions/extension_extent_unittest.cc deleted file mode 100644 index 4e308fa..0000000 --- a/chrome/common/extensions/extension_extent_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2010 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/extension.h" - -#include "googleurl/src/gurl.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(ExtensionExtentTest, Empty) { - ExtensionExtent extent; - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.foo.com/bar"))); - EXPECT_FALSE(extent.ContainsURL(GURL())); - EXPECT_FALSE(extent.ContainsURL(GURL("invalid"))); -} - -TEST(ExtensionExtentTest, OriginOnly) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo/bar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/?stuff#here"))); - - EXPECT_FALSE(extent.ContainsURL(GURL("https://www.google.com/"))); - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com:8080/"))); -} - -TEST(ExtensionExtentTest, OriginAndOnePath) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - extent.add_path("foo"); - - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/"))); - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/fo"))); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/FOO"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo/bar"))); -} - -TEST(ExtensionExtentTest, OriginAndTwoPaths) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - extent.add_path("foo"); - extent.add_path("hot"); - - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/monkey"))); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/hot"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/hotdog"))); -} diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc deleted file mode 100644 index d7a5c2b..0000000 --- a/chrome/common/extensions/extension_manifests_unittest.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2010 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 "base/file_path.h" -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/scoped_ptr.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/extensions/extension_error_utils.h" -#include "chrome/common/json_value_serializer.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace errors = extension_manifest_errors; - -class ManifestTest : public testing::Test { - public: - ManifestTest() : enable_apps_(true) {} - - protected: - Extension* LoadExtension(const std::string& name, - std::string* error) { - FilePath path; - PathService::Get(chrome::DIR_TEST_DATA, &path); - path = path.AppendASCII("extensions") - .AppendASCII("manifest_tests") - .AppendASCII(name.c_str()); - EXPECT_TRUE(file_util::PathExists(path)); - - JSONFileValueSerializer serializer(path); - scoped_ptr<DictionaryValue> value( - static_cast<DictionaryValue*>(serializer.Deserialize(error))); - if (!value.get()) - return NULL; - - scoped_ptr<Extension> extension(new Extension(path.DirName())); - if (enable_apps_) - extension->set_apps_enabled(true); - - if (!extension->InitFromValue(*value, false, error)) - return NULL; - - return extension.release(); - } - - Extension* LoadAndExpectSuccess(const std::string& name) { - std::string error; - Extension* extension = LoadExtension(name, &error); - EXPECT_TRUE(extension); - EXPECT_EQ("", error); - return extension; - } - - void LoadAndExpectError(const std::string& name, - const std::string& expected_error) { - std::string error; - scoped_ptr<Extension> extension(LoadExtension(name, &error)); - EXPECT_FALSE(extension.get()) << - "Expected failure loading extension '" << name << - "', but didn't get one."; - EXPECT_EQ(expected_error, error); - } - - bool enable_apps_; -}; - -TEST_F(ManifestTest, AppsDisabledByDefault) { - enable_apps_ = false; - LoadAndExpectError("web_content_disabled.json", errors::kAppsNotEnabled); - LoadAndExpectError("launch_local_path.json", errors::kAppsNotEnabled); -} - -TEST_F(ManifestTest, ValidApp) { - scoped_ptr<Extension> extension(LoadAndExpectSuccess("valid_app.json")); - EXPECT_TRUE(extension->web_content_enabled()); - EXPECT_EQ(GURL("http://www.google.com/"), extension->web_extent().origin()); - EXPECT_EQ(2u, extension->web_extent().paths().size()); - EXPECT_EQ("mail/", extension->web_extent().paths()[0]); - EXPECT_EQ("foobar/", extension->web_extent().paths()[1]); - EXPECT_EQ(Extension::LAUNCH_WINDOW, extension->launch_container()); - EXPECT_EQ("mail/", extension->launch_web_url()); -} - -TEST_F(ManifestTest, AppWebContentEnabled) { - LoadAndExpectError("web_content_enabled_invalid.json", - errors::kInvalidWebContentEnabled); - LoadAndExpectError("web_content_disabled.json", - errors::kWebContentMustBeEnabled); - LoadAndExpectError("web_content_not_enabled.json", - errors::kWebContentMustBeEnabled); -} - -TEST_F(ManifestTest, AppWebOrigin) { - LoadAndExpectError("web_origin_wrong_type.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_1.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_2.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_3.json", - errors::kInvalidWebOrigin); -} - -TEST_F(ManifestTest, AppWebPaths) { - LoadAndExpectError("web_paths_wrong_type.json", - errors::kInvalidWebPaths); - LoadAndExpectError("web_paths_invalid_path_1.json", - ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, "0")); - LoadAndExpectError("web_paths_invalid_path_2.json", - ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, "0")); -} - -TEST_F(ManifestTest, AppLaunchContainer) { - scoped_ptr<Extension> extension; - - extension.reset(LoadAndExpectSuccess("launch_tab.json")); - EXPECT_EQ(Extension::LAUNCH_TAB, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_window.json")); - EXPECT_EQ(Extension::LAUNCH_WINDOW, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_panel.json")); - EXPECT_EQ(Extension::LAUNCH_PANEL, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_default.json")); - EXPECT_EQ(Extension::LAUNCH_TAB, extension->launch_container()); - - LoadAndExpectError("launch_container_invalid_type.json", - errors::kInvalidLaunchContainer); - LoadAndExpectError("launch_container_invalid_value.json", - errors::kInvalidLaunchContainer); - LoadAndExpectError("launch_container_without_launch_url.json", - errors::kLaunchContainerWithoutURL); -} - -TEST_F(ManifestTest, AppLaunchURL) { - LoadAndExpectError("launch_path_and_url.json", - errors::kLaunchPathAndURLAreExclusive); - LoadAndExpectError("launch_path_invalid_type.json", - errors::kInvalidLaunchLocalPath); - LoadAndExpectError("launch_path_invalid_value.json", - errors::kInvalidLaunchLocalPath); - LoadAndExpectError("launch_url_invalid_type.json", - errors::kInvalidLaunchWebURL); - - scoped_ptr<Extension> extension; - extension.reset(LoadAndExpectSuccess("launch_local_path.json")); - EXPECT_EQ(extension->url().spec() + "launch.html", - extension->GetFullLaunchURL().spec()); - - extension.reset(LoadAndExpectSuccess("launch_web_url_relative.json")); - EXPECT_EQ(GURL("http://www.google.com/launch.html"), - extension->GetFullLaunchURL()); - - extension.reset(LoadAndExpectSuccess("launch_web_url_absolute.json")); - EXPECT_EQ(GURL("http://www.google.com/launch.html"), - extension->GetFullLaunchURL()); -} diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index d046503..4dbb7e3 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc @@ -36,13 +36,6 @@ TEST(ExtensionTest, LocationValuesTest) { ASSERT_EQ(5, Extension::COMPONENT); } - -// Please don't put any more manifest tests here!! -// Move them to extension_manifest_unittest.cc instead and make them use the -// more data-driven style there instead. -// Bug: http://crbug.com/38462 - - TEST(ExtensionTest, InitFromValueInvalid) { #if defined(OS_WIN) FilePath path(FILE_PATH_LITERAL("c:\\foo")); @@ -281,6 +274,58 @@ TEST(ExtensionTest, InitFromValueInvalid) { EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPatternASCII(error, errors::kChromeVersionTooLow)); #endif + + // Test invalid app. + input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); + input_value->Set(keys::kApp, Value::CreateIntegerValue(42)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidApp, error); + + // Test invalid launch URLs. + DictionaryValue* app = new DictionaryValue(); + input_value->Set(keys::kApp, app); + + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppLaunchUrl, error); + + Value* invalid_launch_urls[] = { + Value::CreateStringValue(""), + Value::CreateIntegerValue(42), + Value::CreateStringValue("foobar") + }; + + for (size_t i = 0; i < arraysize(invalid_launch_urls); ++i) { + app->Set(keys::kAppLaunchUrl, invalid_launch_urls[i]); + error.clear(); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppLaunchUrl, error); + } + + // Test valid launch URL. + app->Set(keys::kAppLaunchUrl, + Value::CreateStringValue("http://www.google.com/index.html")); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); + + // Test invalid app origins. + Value* invalid_origins[] = { + Value::CreateStringValue(""), + Value::CreateIntegerValue(42), + Value::CreateStringValue("foobar"), + Value::CreateStringValue("file:///c:/foo.txt"), + Value::CreateStringValue("ftp://www.google.com/") + }; + + for (size_t i = 0; i < arraysize(invalid_origins); ++i) { + app->Set(keys::kAppOrigin, invalid_origins[i]); + error.clear(); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppOrigin, error); + } + + // Test valid origin. + app->Set(keys::kAppOrigin, + Value::CreateStringValue("http://www.google.com/")); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); } TEST(ExtensionTest, InitFromValueValid) { |