diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 02:20:48 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-06 02:20:48 +0000 |
commit | f58fa27cc3dbf581c074764ec6d64219949f2146 (patch) | |
tree | 8d009fc6f7e580e2e8b68f30074644eb99cb08fa | |
parent | 1ff67fb4bb72dfc919ca9f16a8d4dcab983bc02c (diff) | |
download | chromium_src-f58fa27cc3dbf581c074764ec6d64219949f2146.zip chromium_src-f58fa27cc3dbf581c074764ec6d64219949f2146.tar.gz chromium_src-f58fa27cc3dbf581c074764ec6d64219949f2146.tar.bz2 |
Add a "minimum_chrome_version" key to the manifest.
BUG=24737
Review URL: http://codereview.chromium.org/521036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35602 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/chrome_dll_main.cc | 3 | ||||
-rw-r--r-- | chrome/common/extensions/docs/manifest.html | 12 | ||||
-rw-r--r-- | chrome/common/extensions/docs/static/manifest.html | 8 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 43 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 13 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 3 | ||||
-rw-r--r-- | chrome/common/extensions/extension_unittest.cc | 20 |
7 files changed, 94 insertions, 8 deletions
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc index b47c82e..8ef4314 100644 --- a/chrome/app/chrome_dll_main.cc +++ b/chrome/app/chrome_dll_main.cc @@ -352,7 +352,8 @@ bool SubprocessNeedsResourceBundle(const std::string& process_type) { process_type == switches::kZygoteProcess || #endif process_type == switches::kRendererProcess || - process_type == switches::kExtensionProcess; + process_type == switches::kExtensionProcess || + process_type == switches::kUtilityProcess; } } // namespace diff --git a/chrome/common/extensions/docs/manifest.html b/chrome/common/extensions/docs/manifest.html index 8383376..d6c3e40 100644 --- a/chrome/common/extensions/docs/manifest.html +++ b/chrome/common/extensions/docs/manifest.html @@ -210,6 +210,8 @@ </li><li> <a href="#name">name</a> </li><li> + <a href="#minimum_chrome_version">Minimum Chrome Version</a> + </li><li> <a href="#permissions">permissions</a> </li><li> <a href="#version">version</a> @@ -295,6 +297,7 @@ are <b>name</b> and <b>version</b>. "<a href="background_pages.html">background_page</a>": "<em>aFile</em>.html", "<a href="override.html">chrome_url_overrides</a>": {...}, "<a href="content_scripts.html">content_scripts</a>": [...], + "<a href="#minimum_chrome_version">minimum_chrome_version</a>": "x.y", "<a href="options.html">options_page</a>": "<em>aFile</em>.html", "<a href="#permissions">permissions</a>": [...], "<a href="npapi.html">plugins</a>": [...], @@ -370,7 +373,14 @@ extension management UI, and the <a href="https://chrome.google.com/extensions">extension gallery</a>. </p> -<h3 id="permissions">permissions</h3> +<h3 id="minimum_chrome_version">Minimum Chrome Version</h3> + +<p> +The version of Google Chrome that your extension requires, if any. +The format for this string is the same as for the <a href="#version">version +field</a>. + +</p><h3 id="permissions">permissions</h3> <p> An array of permissions that the extension might use. diff --git a/chrome/common/extensions/docs/static/manifest.html b/chrome/common/extensions/docs/static/manifest.html index dfa2c9d..802b26e 100644 --- a/chrome/common/extensions/docs/static/manifest.html +++ b/chrome/common/extensions/docs/static/manifest.html @@ -36,6 +36,7 @@ are <b>name</b> and <b>version</b>. "<a href="background_pages.html">background_page</a>": "<em>aFile</em>.html", "<a href="override.html">chrome_url_overrides</a>": {...}, "<a href="content_scripts.html">content_scripts</a>": [...], + "<a href="#minimum_chrome_version">minimum_chrome_version</a>": "x.y", "<a href="options.html">options_page</a>": "<em>aFile</em>.html", "<a href="#permissions">permissions</a>": [...], "<a href="npapi.html">plugins</a>": [...], @@ -112,6 +113,13 @@ extension management UI, and the <a href="https://chrome.google.com/extensions">extension gallery</a>. </p> +<h3 id="minimum_chrome_version">Minimum Chrome Version</h3> + +<p> +The version of Google Chrome that your extension requires, if any. +The format for this string is the same as for the <a href="#version">version +field</a>. + <h3 id="permissions">permissions</h3> <p> diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 9097086..5dfdf1c 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -4,12 +4,14 @@ #include "chrome/common/extensions/extension.h" +#include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/base64.h" #include "base/basictypes.h" #include "base/command_line.h" #include "base/file_path.h" #include "base/file_util.h" +#include "base/file_version_info.h" #include "base/logging.h" #include "base/string_util.h" #include "base/stl_util-inl.h" @@ -24,6 +26,7 @@ #include "chrome/common/extensions/user_script.h" #include "chrome/common/notification_service.h" #include "chrome/common/url_constants.h" +#include "grit/chromium_strings.h" #include "webkit/glue/image_decoder.h" #if defined(OS_WIN) @@ -757,6 +760,46 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, } } + // Validate minimum Chrome version (if present). We don't need to store this, + // since the extension is not valid if it is incorrect. + if (source.HasKey(keys::kMinimumChromeVersion)) { + std::string minimum_version_string; + if (!source.GetString(keys::kMinimumChromeVersion, + &minimum_version_string)) { + *error = errors::kInvalidMinimumChromeVersion; + return false; + } + + scoped_ptr<Version> minimum_version( + Version::GetVersionFromString(minimum_version_string)); + if (!minimum_version.get()) { + *error = errors::kInvalidMinimumChromeVersion; + return false; + } + + scoped_ptr<FileVersionInfo> current_version_info( + FileVersionInfo::CreateFileVersionInfoForCurrentModule()); + if (!current_version_info.get()) { + DCHECK(false); + return false; + } + + scoped_ptr<Version> current_version( + Version::GetVersionFromString(current_version_info->file_version())); + if (!current_version.get()) { + DCHECK(false); + return false; + } + + if (current_version->CompareTo(*minimum_version) < 0) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kChromeVersionTooLow, + l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), + minimum_version_string); + return false; + } + } + // Initialize converted_from_user_script (if present) source.GetBoolean(keys::kConvertedFromUserScript, &converted_from_user_script_); diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 3deaf20..825fc2e 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -19,6 +19,7 @@ const wchar_t* kDescription = L"description"; const wchar_t* kIcons = L"icons"; const wchar_t* kJs = L"js"; const wchar_t* kMatches = L"matches"; +const wchar_t* kMinimumChromeVersion = L"minimum_chrome_version"; const wchar_t* kIncludeGlobs = L"include_globs"; const wchar_t* kExcludeGlobs = L"exclude_globs"; const wchar_t* kName = L"name"; @@ -67,6 +68,8 @@ const char* kPageActionTypePermanent = "permanent"; // printf because we want to unit test them and scanf is hard to make // cross-platform. namespace extension_manifest_errors { +const char* kChromeVersionTooLow = + "This extension requires * version * or greater."; const char* kInvalidAllFrames = "Invalid value for 'content_scripts[*].all_frames'."; const char* kInvalidBrowserAction = @@ -80,7 +83,7 @@ const char* kInvalidContentScriptsList = const char* kInvalidCss = "Invalid value for 'content_scripts[*].css[*]'."; const char* kInvalidCssList = - "Required value 'content_scripts[*].css is invalid."; + "Required value 'content_scripts[*].css' is invalid."; const char* kInvalidDescription = "Invalid value for 'description'."; const char* kInvalidGlobList = @@ -94,18 +97,20 @@ const char* kInvalidIconPath = const char* kInvalidJs = "Invalid value for 'content_scripts[*].js[*]'."; const char* kInvalidJsList = - "Required value 'content_scripts[*].js is invalid."; + "Required value 'content_scripts[*].js' is invalid."; const char* kInvalidKey = "Value 'key' is missing or invalid."; const char* kInvalidManifest = "Manifest file is invalid."; const char* kInvalidMatchCount = - "Invalid value for 'content_scripts[*].matches. There must be at least one " - "match specified."; + "Invalid value for 'content_scripts[*].matches'. There must be at least" + "one match specified."; const char* kInvalidMatch = "Invalid value for 'content_scripts[*].matches[*]'."; const char* kInvalidMatches = "Required value 'content_scripts[*].matches' is missing or invalid."; +const char* kInvalidMinimumChromeVersion = + "Invalid value for 'minimum_chrome_version'."; const char* kInvalidName = "Required value 'name' is missing or invalid."; const char* kInvalidPageAction = diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index a83c2d8..4d9ef84 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -10,6 +10,7 @@ namespace extension_manifest_keys { extern const wchar_t* kAllFrames; extern const wchar_t* kBackground; extern const wchar_t* kBrowserAction; + extern const wchar_t* kMinimumChromeVersion; extern const wchar_t* kChromeURLOverrides; extern const wchar_t* kContentScripts; extern const wchar_t* kConvertedFromUserScript; @@ -66,6 +67,7 @@ namespace extension_manifest_values { // Error messages returned from Extension::InitFromValue(). namespace extension_manifest_errors { + extern const char* kChromeVersionTooLow; extern const char* kInvalidBrowserAction; extern const char* kInvalidChromeURLOverrides; extern const char* kInvalidContentScript; @@ -84,6 +86,7 @@ namespace extension_manifest_errors { extern const char* kInvalidMatchCount; extern const char* kInvalidMatch; extern const char* kInvalidMatches; + extern const char* kInvalidMinimumChromeVersion; extern const char* kInvalidName; extern const char* kInvalidPlugins; extern const char* kInvalidPluginsPath; diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index db992eb..677e1f8 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc @@ -23,8 +23,7 @@ namespace errors = extension_manifest_errors; class ExtensionTest : public testing::Test { }; -// TODO(mad): http://crbug.com/26214 -TEST(ExtensionTest, DISABLED_InitFromValueInvalid) { +TEST(ExtensionTest, InitFromValueInvalid) { #if defined(OS_WIN) FilePath path(FILE_PATH_LITERAL("c:\\foo")); #elif defined(OS_POSIX) @@ -251,6 +250,17 @@ TEST(ExtensionTest, DISABLED_InitFromValueInvalid) { input_value->Set(keys::kDefaultLocale, Value::CreateStringValue("")); EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPatternASCII(error, errors::kInvalidDefaultLocale)); + + // Test invalid minimum_chrome_version. + input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); + input_value->Set(keys::kMinimumChromeVersion, Value::CreateIntegerValue(42)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_TRUE(MatchPatternASCII(error, errors::kInvalidMinimumChromeVersion)); + + input_value->Set(keys::kMinimumChromeVersion, + Value::CreateStringValue("88.8")); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_TRUE(MatchPatternASCII(error, errors::kChromeVersionTooLow)); } TEST(ExtensionTest, InitFromValueValid) { @@ -281,6 +291,12 @@ TEST(ExtensionTest, InitFromValueValid) { EXPECT_EQ("", error); EXPECT_EQ("chrome-extension", extension.options_url().scheme()); EXPECT_EQ("/options.html", extension.options_url().path()); + + // Test with a minimum_chrome_version. + input_value.SetString(keys::kMinimumChromeVersion, "1.0"); + EXPECT_TRUE(extension.InitFromValue(input_value, false, &error)); + EXPECT_EQ("", error); + // The minimum chrome version is not stored in the Extension object. } TEST(ExtensionTest, GetResourceURLAndPath) { |