summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/extension_action/browser_action_unittest.cc70
-rw-r--r--chrome/browser/extensions/extension_action_manager_unittest.cc21
-rw-r--r--chrome/browser/extensions/extension_service_test_with_install.cc14
-rw-r--r--chrome/browser/extensions/extension_service_test_with_install.h3
-rw-r--r--chrome/chrome_tests_unit.gypi1
-rw-r--r--chrome/common/extensions/api/extension_action/action_info.cc4
-rw-r--r--chrome/common/extensions/api/extension_action/action_info.h2
-rw-r--r--chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc2
-rw-r--r--chrome/common/extensions/manifest_tests/extension_manifests_icons_unittest.cc17
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/missing_icon/icon24.pngbin0 -> 2799 bytes
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/missing_icon/icon38.pngbin0 -> 2799 bytes
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/missing_icon/manifest.json12
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/multi_icons/icon19.pngbin0 -> 2799 bytes
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/multi_icons/icon24.pngbin0 -> 2799 bytes
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/multi_icons/icon38.pngbin0 -> 2799 bytes
-rw-r--r--chrome/test/data/extensions/api_test/browser_action/multi_icons/manifest.json13
-rw-r--r--extensions/common/file_util.cc17
-rw-r--r--extensions/common/file_util.h3
-rw-r--r--extensions/common/file_util_unittest.cc28
-rw-r--r--extensions/common/manifest_handler_helpers.cc25
-rw-r--r--extensions/common/manifest_handler_helpers.h11
-rw-r--r--extensions/common/manifest_handlers/icons_handler.cc2
-rw-r--r--extensions/test/data/file_util/bad_icon/good-icon.pngbin0 -> 160 bytes
-rw-r--r--extensions/test/data/file_util/bad_icon/manifest.json4
-rw-r--r--extensions/utility/unpacker.cc5
25 files changed, 214 insertions, 40 deletions
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_unittest.cc b/chrome/browser/extensions/api/extension_action/browser_action_unittest.cc
new file mode 100644
index 0000000..8060e9e
--- /dev/null
+++ b/chrome/browser/extensions/api/extension_action/browser_action_unittest.cc
@@ -0,0 +1,70 @@
+// Copyright 2015 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/files/file_util.h"
+#include "chrome/browser/extensions/extension_service_test_with_install.h"
+#include "chrome/common/extensions/api/extension_action/action_info.h"
+
+namespace extensions {
+namespace {
+
+class BrowserActionUnitTest : public ExtensionServiceTestWithInstall {
+};
+
+TEST_F(BrowserActionUnitTest, MultiIcons) {
+ InitializeEmptyExtensionService();
+ base::FilePath path =
+ data_dir().AppendASCII("api_test/browser_action/multi_icons");
+ ASSERT_TRUE(base::PathExists(path));
+
+ const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
+
+ EXPECT_EQ(0U, extension->install_warnings().size());
+ const ActionInfo* browser_action_info =
+ ActionInfo::GetBrowserActionInfo(extension);
+ ASSERT_TRUE(browser_action_info);
+
+ const ExtensionIconSet& icons = browser_action_info->default_icon;
+
+ // Extension can provide arbitrary sizes.
+ EXPECT_EQ(4u, icons.map().size());
+ EXPECT_EQ("icon19.png", icons.Get(19, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icon24.png", icons.Get(24, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icon24.png", icons.Get(31, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icon38.png", icons.Get(38, ExtensionIconSet::MATCH_EXACTLY));
+}
+
+TEST_F(BrowserActionUnitTest, MissingIconInWebstoreCrx) {
+ InitializeEmptyExtensionService();
+ base::FilePath path =
+ data_dir().AppendASCII("api_test/browser_action/missing_icon");
+ ASSERT_TRUE(base::PathExists(path));
+
+ const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
+
+ ASSERT_EQ(1U, extension->install_warnings().size());
+ EXPECT_EQ("Could not load extension icon 'icon19.png'.",
+ extension->install_warnings().front().message);
+ const ActionInfo* browser_action_info =
+ ActionInfo::GetBrowserActionInfo(extension);
+ ASSERT_TRUE(browser_action_info);
+
+ const ExtensionIconSet& icons = browser_action_info->default_icon;
+
+ EXPECT_EQ(2u, icons.map().size());
+ EXPECT_EQ("icon24.png", icons.Get(24, ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("icon38.png", icons.Get(38, ExtensionIconSet::MATCH_EXACTLY));
+}
+
+TEST_F(BrowserActionUnitTest, MissingIconInCommandLine) {
+ InitializeEmptyExtensionService();
+ base::FilePath path =
+ data_dir().AppendASCII("api_test/browser_action/missing_icon");
+ ASSERT_TRUE(base::PathExists(path));
+
+ PackAndInstallCRXWithLocation(path, Manifest::COMMAND_LINE, INSTALL_FAILED);
+}
+
+} // namespace
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_action_manager_unittest.cc b/chrome/browser/extensions/extension_action_manager_unittest.cc
index d040762..76c47f1 100644
--- a/chrome/browser/extensions/extension_action_manager_unittest.cc
+++ b/chrome/browser/extensions/extension_action_manager_unittest.cc
@@ -75,15 +75,18 @@ scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension(
DictionaryBuilder& action,
const char* action_type) {
std::string id = base::IntToString(curr_id_++);
- scoped_refptr<Extension> extension = ExtensionBuilder()
- .SetManifest(DictionaryBuilder().Set("version", "1")
- .Set("manifest_version", 2)
- .Set("icons", extension_icons)
- .Set(action_type, action)
- .Set("name",
- std::string("Test Extension").append(id)))
- .SetID(id)
- .Build();
+ scoped_refptr<Extension> extension =
+ ExtensionBuilder()
+ .SetManifest(
+ DictionaryBuilder()
+ .Set("version", "1")
+ .Set("manifest_version", 2)
+ .Set("icons", extension_icons)
+ .Set(action_type, action)
+ .Set("name", std::string("Test Extension").append(id)))
+ .SetLocation(Manifest::UNPACKED)
+ .SetID(id)
+ .Build();
registry_->AddEnabled(extension);
return extension;
}
diff --git a/chrome/browser/extensions/extension_service_test_with_install.cc b/chrome/browser/extensions/extension_service_test_with_install.cc
index f2cedef..8f93b2c 100644
--- a/chrome/browser/extensions/extension_service_test_with_install.cc
+++ b/chrome/browser/extensions/extension_service_test_with_install.cc
@@ -126,6 +126,20 @@ const Extension* ExtensionServiceTestWithInstall::PackAndInstallCRX(
Extension::NO_FLAGS);
}
+const Extension* ExtensionServiceTestWithInstall::PackAndInstallCRXWithLocation(
+ const base::FilePath& dir_path,
+ Manifest::Location location,
+ InstallState install_state) {
+ // TODO(devlin): reuse another function instead of reimplementing here.
+ base::FilePath crx_path;
+ base::ScopedTempDir temp_dir;
+ EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
+ crx_path = temp_dir.path().AppendASCII("temp.crx");
+
+ PackCRX(dir_path, base::FilePath(), crx_path);
+ return InstallCRXWithLocation(crx_path, location, install_state);
+}
+
// Attempts to install an extension. Use INSTALL_FAILED if the installation
// is expected to fail.
// If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
diff --git a/chrome/browser/extensions/extension_service_test_with_install.h b/chrome/browser/extensions/extension_service_test_with_install.h
index 0ad20eb..a6c3cad 100644
--- a/chrome/browser/extensions/extension_service_test_with_install.h
+++ b/chrome/browser/extensions/extension_service_test_with_install.h
@@ -56,6 +56,9 @@ class ExtensionServiceTestWithInstall : public ExtensionServiceTestBase,
InstallState install_state);
const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
InstallState install_state);
+ const Extension* PackAndInstallCRXWithLocation(const base::FilePath& dir_path,
+ Manifest::Location location,
+ InstallState install_state);
const Extension* InstallCRX(const base::FilePath& path,
InstallState install_state,
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 0e99851..258cf2d 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -431,6 +431,7 @@
'browser/extensions/api/dial/dial_service_unittest.cc',
'browser/extensions/api/easy_unlock_private/easy_unlock_private_api_chromeos_unittest.cc',
'browser/extensions/api/experience_sampling_private/experience_sampling_private_api_unittest.cc',
+ 'browser/extensions/api/extension_action/browser_action_unittest.cc',
'browser/extensions/api/extension_action/extension_action_prefs_unittest.cc',
'browser/extensions/api/file_handlers/api_file_handler_util_unittest.cc',
'browser/extensions/api/file_handlers/mime_util_unittest.cc',
diff --git a/chrome/common/extensions/api/extension_action/action_info.cc b/chrome/common/extensions/api/extension_action/action_info.cc
index 4059a9d..dcc6ce0 100644
--- a/chrome/common/extensions/api/extension_action/action_info.cc
+++ b/chrome/common/extensions/api/extension_action/action_info.cc
@@ -52,7 +52,7 @@ ActionInfo::~ActionInfo() {
}
// static
-scoped_ptr<ActionInfo> ActionInfo::Load(const Extension* extension,
+scoped_ptr<ActionInfo> ActionInfo::Load(Extension* extension,
const base::DictionaryValue* dict,
base::string16* error) {
scoped_ptr<ActionInfo> result(new ActionInfo());
@@ -92,7 +92,7 @@ scoped_ptr<ActionInfo> ActionInfo::Load(const Extension* extension,
std::string default_icon;
if (dict->GetDictionary(keys::kPageActionDefaultIcon, &icons_value)) {
if (!manifest_handler_helpers::LoadIconsFromDictionary(
- icons_value, &result->default_icon, error)) {
+ extension, icons_value, &result->default_icon, error)) {
return scoped_ptr<ActionInfo>();
}
} else if (dict->GetString(keys::kPageActionDefaultIcon, &default_icon) &&
diff --git a/chrome/common/extensions/api/extension_action/action_info.h b/chrome/common/extensions/api/extension_action/action_info.h
index 09e497c..3ad0a25 100644
--- a/chrome/common/extensions/api/extension_action/action_info.h
+++ b/chrome/common/extensions/api/extension_action/action_info.h
@@ -32,7 +32,7 @@ struct ActionInfo {
};
// Loads an ActionInfo from the given DictionaryValue.
- static scoped_ptr<ActionInfo> Load(const Extension* extension,
+ static scoped_ptr<ActionInfo> Load(Extension* extension,
const base::DictionaryValue* dict,
base::string16* error);
diff --git a/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc b/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc
index 539477b..ea7b4be 100644
--- a/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc
+++ b/chrome/common/extensions/api/extension_action/browser_action_manifest_unittest.cc
@@ -81,6 +81,8 @@ TEST_F(BrowserActionManifestTest,
.Set("19", "icon19.png")
.Set("24", "icon24.png")
.Set("38", "icon38.png"))))
+ // Don't check for existence of icons during parsing.
+ .SetLocation(Manifest::UNPACKED)
.Build();
ASSERT_TRUE(extension.get());
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_icons_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_icons_unittest.cc
index e73ba82..0a7a41f 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_icons_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_icons_unittest.cc
@@ -15,9 +15,22 @@ namespace extensions {
class IconsManifestTest : public ChromeManifestTest {
};
+// Icons that don't exist on disk should be ignored (for most manifest
+// locations).
+TEST_F(IconsManifestTest, IgnoreNonExistentIcons) {
+ scoped_refptr<extensions::Extension> extension(
+ LoadAndExpectSuccess("normalize_icon_paths.json", Manifest::INTERNAL));
+ const ExtensionIconSet& icons = IconsInfo::GetIcons(extension.get());
+
+ EXPECT_EQ("", icons.Get(extension_misc::EXTENSION_ICON_BITTY,
+ ExtensionIconSet::MATCH_EXACTLY));
+ EXPECT_EQ("", icons.Get(extension_misc::EXTENSION_ICON_MEDIUM,
+ ExtensionIconSet::MATCH_EXACTLY));
+}
+
TEST_F(IconsManifestTest, NormalizeIconPaths) {
scoped_refptr<extensions::Extension> extension(
- LoadAndExpectSuccess("normalize_icon_paths.json"));
+ LoadAndExpectSuccess("normalize_icon_paths.json", Manifest::UNPACKED));
const ExtensionIconSet& icons = IconsInfo::GetIcons(extension.get());
EXPECT_EQ("16.png", icons.Get(extension_misc::EXTENSION_ICON_BITTY,
@@ -28,7 +41,7 @@ TEST_F(IconsManifestTest, NormalizeIconPaths) {
TEST_F(IconsManifestTest, IconSizes) {
scoped_refptr<extensions::Extension> extension(
- LoadAndExpectSuccess("init_icon_size.json"));
+ LoadAndExpectSuccess("init_icon_size.json", Manifest::UNPACKED));
const ExtensionIconSet& icons = IconsInfo::GetIcons(extension.get());
EXPECT_EQ("16.png", icons.Get(extension_misc::EXTENSION_ICON_BITTY,
diff --git a/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon24.png b/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon24.png
new file mode 100644
index 0000000..84c4be3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon24.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon38.png b/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon38.png
new file mode 100644
index 0000000..84c4be3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/missing_icon/icon38.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/browser_action/missing_icon/manifest.json b/chrome/test/data/extensions/api_test/browser_action/missing_icon/manifest.json
new file mode 100644
index 0000000..7f6df45
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/missing_icon/manifest.json
@@ -0,0 +1,12 @@
+{
+ "name": "A test extension that tests multiple browser action icons",
+ "version": "1.0",
+ "manifest_version": 2,
+ "browser_action": {
+ "default_icon": {
+ "19": "icon19.png",
+ "24": "icon24.png",
+ "38": "icon38.png"
+ }
+ }
+}
diff --git a/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon19.png b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon19.png
new file mode 100644
index 0000000..84c4be3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon19.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon24.png b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon24.png
new file mode 100644
index 0000000..84c4be3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon24.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon38.png b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon38.png
new file mode 100644
index 0000000..84c4be3
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/multi_icons/icon38.png
Binary files differ
diff --git a/chrome/test/data/extensions/api_test/browser_action/multi_icons/manifest.json b/chrome/test/data/extensions/api_test/browser_action/multi_icons/manifest.json
new file mode 100644
index 0000000..694d8102
--- /dev/null
+++ b/chrome/test/data/extensions/api_test/browser_action/multi_icons/manifest.json
@@ -0,0 +1,13 @@
+{
+ "name": "A test extension that tests multiple browser action icons",
+ "version": "1.0",
+ "manifest_version": 2,
+ "browser_action": {
+ "default_icon": {
+ "19": "icon19.png",
+ "24": "icon24.png",
+ "31": "icon24.png",
+ "38": "icon38.png"
+ }
+ }
+}
diff --git a/extensions/common/file_util.cc b/extensions/common/file_util.cc
index a187378..a42bdae 100644
--- a/extensions/common/file_util.cc
+++ b/extensions/common/file_util.cc
@@ -52,18 +52,6 @@ enum SafeInstallationFlag {
};
SafeInstallationFlag g_use_safe_installation = DEFAULT;
-// Returns true if the given file path exists and is not zero-length.
-bool ValidateFilePath(const base::FilePath& path) {
- int64 size = 0;
- if (!base::PathExists(path) ||
- !base::GetFileSize(path, &size) ||
- size == 0) {
- return false;
- }
-
- return true;
-}
-
// Returns true if the extension installation should flush all files and the
// directory.
bool UseSafeInstallation() {
@@ -271,6 +259,11 @@ scoped_ptr<base::DictionaryValue> LoadManifest(
return base::DictionaryValue::From(std::move(root));
}
+bool ValidateFilePath(const base::FilePath& path) {
+ int64 size = 0;
+ return base::PathExists(path) && base::GetFileSize(path, &size) && size != 0;
+}
+
bool ValidateExtension(const Extension* extension,
std::string* error,
std::vector<InstallWarning>* warnings) {
diff --git a/extensions/common/file_util.h b/extensions/common/file_util.h
index 3fda56a..609b27c 100644
--- a/extensions/common/file_util.h
+++ b/extensions/common/file_util.h
@@ -72,6 +72,9 @@ scoped_ptr<base::DictionaryValue> LoadManifest(
const base::FilePath::CharType* manifest_filename,
std::string* error);
+// Returns true if the given file path exists and is not zero-length.
+bool ValidateFilePath(const base::FilePath& path);
+
// Returns true if the given extension object is valid and consistent.
// May also append a series of warning messages to |warnings|, but they
// should not prevent the extension from running.
diff --git a/extensions/common/file_util_unittest.cc b/extensions/common/file_util_unittest.cc
index 634b338..5148737 100644
--- a/extensions/common/file_util_unittest.cc
+++ b/extensions/common/file_util_unittest.cc
@@ -416,19 +416,39 @@ TEST_F(FileUtilTest, WarnOnPrivateKey) {
"extension includes the key file.*ext_root.a_key.pem"));
}
-TEST_F(FileUtilTest, CheckZeroLengthIconFile) {
+// Try to install an extension with a zero-length icon file.
+TEST_F(FileUtilTest, CheckZeroLengthAndMissingIconFile) {
+ base::FilePath install_dir;
+ ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &install_dir));
+
+ base::FilePath ext_dir =
+ install_dir.AppendASCII("file_util").AppendASCII("bad_icon");
+
+ std::string error;
+ scoped_refptr<Extension> extension(file_util::LoadExtension(
+ ext_dir, Manifest::INTERNAL, Extension::NO_FLAGS, &error));
+ EXPECT_TRUE(extension);
+ ASSERT_EQ(2U, extension->install_warnings().size());
+
+ EXPECT_EQ("Could not load extension icon 'missing-icon.png'.",
+ extension->install_warnings()[0].message);
+ EXPECT_EQ("Could not load extension icon 'icon.png'.",
+ extension->install_warnings()[1].message);
+}
+
+// Try to install an unpacked extension with a zero-length icon file.
+TEST_F(FileUtilTest, CheckZeroLengthAndMissingIconFileUnpacked) {
base::FilePath install_dir;
ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &install_dir));
- // Try to install an extension with a zero-length icon file.
base::FilePath ext_dir =
install_dir.AppendASCII("file_util").AppendASCII("bad_icon");
std::string error;
scoped_refptr<Extension> extension(file_util::LoadExtension(
ext_dir, Manifest::UNPACKED, Extension::NO_FLAGS, &error));
- EXPECT_TRUE(extension.get() == NULL);
- EXPECT_STREQ("Could not load extension icon 'icon.png'.", error.c_str());
+ EXPECT_FALSE(extension);
+ EXPECT_EQ("Could not load extension icon 'missing-icon.png'.", error);
}
TEST_F(FileUtilTest, ExtensionURLToRelativeFilePath) {
diff --git a/extensions/common/manifest_handler_helpers.cc b/extensions/common/manifest_handler_helpers.cc
index 4dc2f6b..f04d0f8 100644
--- a/extensions/common/manifest_handler_helpers.cc
+++ b/extensions/common/manifest_handler_helpers.cc
@@ -11,8 +11,10 @@
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_icon_set.h"
+#include "extensions/common/file_util.h"
#include "extensions/common/manifest_constants.h"
-
+#include "grit/extensions_strings.h"
+#include "ui/base/l10n/l10n_util.h"
namespace extensions {
@@ -31,7 +33,8 @@ bool NormalizeAndValidatePath(std::string* path) {
return true;
}
-bool LoadIconsFromDictionary(const base::DictionaryValue* icons_value,
+bool LoadIconsFromDictionary(Extension* extension,
+ const base::DictionaryValue* icons_value,
ExtensionIconSet* icons,
base::string16* error) {
DCHECK(icons);
@@ -48,7 +51,23 @@ bool LoadIconsFromDictionary(const base::DictionaryValue* icons_value,
return false;
}
- icons->Add(size, icon_path);
+ // For backwards compatibility, only warn (don't error out) if an icon is
+ // missing. Component extensions can skip this check as their icons are not
+ // located on disk. Unpacked extensions skip this check and fail later
+ // during validation if the file isn't present. See crbug.com/570249
+ // TODO(estade|devlin): remove this workaround and let install fail in the
+ // validate step a few releases after M49. See http://crbug.com/571193
+ if (Manifest::IsComponentLocation(extension->location()) ||
+ Manifest::IsUnpackedLocation(extension->location()) ||
+ file_util::ValidateFilePath(
+ extension->GetResource(icon_path).GetFilePath())) {
+ icons->Add(size, icon_path);
+ } else {
+ extension->AddInstallWarning(InstallWarning(
+ l10n_util::GetStringFUTF8(IDS_EXTENSION_LOAD_ICON_FAILED,
+ base::UTF8ToUTF16(icon_path)),
+ std::string()));
+ }
}
return true;
}
diff --git a/extensions/common/manifest_handler_helpers.h b/extensions/common/manifest_handler_helpers.h
index b0249c3..e1f901a 100644
--- a/extensions/common/manifest_handler_helpers.h
+++ b/extensions/common/manifest_handler_helpers.h
@@ -6,9 +6,11 @@
#define EXTENSIONS_COMMON_MANIFEST_HANDLER_HELPERS_H_
#include <string>
+#include <vector>
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
+#include "extensions/common/install_warning.h"
class ExtensionIconSet;
@@ -17,6 +19,9 @@ class DictionaryValue;
}
namespace extensions {
+
+class Extension;
+
namespace manifest_handler_helpers {
// Strips leading slashes from the file path. Returns true iff the final path is
@@ -25,8 +30,10 @@ bool NormalizeAndValidatePath(std::string* path);
// Loads icon paths defined in dictionary |icons_value| into ExtensionIconSet
// |icons|. |icons_value| is a dictionary value {icon size -> icon path}.
-// Returns success. If load fails, |error| will be set.
-bool LoadIconsFromDictionary(const base::DictionaryValue* icons_value,
+// Returns success. If load fails, |error| will be set. Non-failure warnings may
+// be added to |extension|.
+bool LoadIconsFromDictionary(Extension* extension,
+ const base::DictionaryValue* icons_value,
ExtensionIconSet* icons,
base::string16* error);
diff --git a/extensions/common/manifest_handlers/icons_handler.cc b/extensions/common/manifest_handlers/icons_handler.cc
index 20ad025..52597e5 100644
--- a/extensions/common/manifest_handlers/icons_handler.cc
+++ b/extensions/common/manifest_handlers/icons_handler.cc
@@ -64,7 +64,7 @@ bool IconsHandler::Parse(Extension* extension, base::string16* error) {
}
if (!manifest_handler_helpers::LoadIconsFromDictionary(
- icons_dict, &icons_info->icons, error)) {
+ extension, icons_dict, &icons_info->icons, error)) {
return false;
}
diff --git a/extensions/test/data/file_util/bad_icon/good-icon.png b/extensions/test/data/file_util/bad_icon/good-icon.png
new file mode 100644
index 0000000..d89ed60
--- /dev/null
+++ b/extensions/test/data/file_util/bad_icon/good-icon.png
Binary files differ
diff --git a/extensions/test/data/file_util/bad_icon/manifest.json b/extensions/test/data/file_util/bad_icon/manifest.json
index e3846e4..27b7dac 100644
--- a/extensions/test/data/file_util/bad_icon/manifest.json
+++ b/extensions/test/data/file_util/bad_icon/manifest.json
@@ -2,7 +2,9 @@
"name": "My extension with a zero-length icon",
"version": "1.0",
"icons": {
- "16": "icon.png"
+ "16": "good-icon.png",
+ "32": "missing-icon.png",
+ "64": "icon.png"
},
"manifest_version": 2
}
diff --git a/extensions/utility/unpacker.cc b/extensions/utility/unpacker.cc
index 36c0eba..4763268 100644
--- a/extensions/utility/unpacker.cc
+++ b/extensions/utility/unpacker.cc
@@ -185,9 +185,8 @@ bool Unpacker::Run() {
// Decode any images that the browser needs to display.
std::set<base::FilePath> image_paths =
ExtensionsClient::Get()->GetBrowserImagePaths(extension.get());
- for (std::set<base::FilePath>::iterator it = image_paths.begin();
- it != image_paths.end(); ++it) {
- if (!AddDecodedImage(*it))
+ for (const base::FilePath& path : image_paths) {
+ if (!AddDecodedImage(path))
return false; // Error was already reported.
}