summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authorrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 20:16:09 +0000
committerrafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-11 20:16:09 +0000
commit928bfd79b3646f46451f439dd13e0871d97cc20c (patch)
tree9b1d92f4c54e11e288a1ebfdc2252c819f770b4f /chrome/common
parentb17ef85af94338657109d2c85de8c26b88432f89 (diff)
downloadchromium_src-928bfd79b3646f46451f439dd13e0871d97cc20c.zip
chromium_src-928bfd79b3646f46451f439dd13e0871d97cc20c.tar.gz
chromium_src-928bfd79b3646f46451f439dd13e0871d97cc20c.tar.bz2
BUG=12114
R=erikkay,wtc Review URL: http://codereview.chromium.org/115682 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18189 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/extensions/extension.cc78
-rw-r--r--chrome/common/extensions/extension.h39
-rw-r--r--chrome/common/extensions/extension_unittest.cc25
-rw-r--r--chrome/common/extensions/extension_unpacker.cc136
-rw-r--r--chrome/common/extensions/extension_unpacker.h4
5 files changed, 105 insertions, 177 deletions
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index bf7d3a5..73eb417 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -5,10 +5,14 @@
#include "chrome/common/extensions/extension.h"
#include "app/resource_bundle.h"
+#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/string_util.h"
+#include "base/third_party/nss/blapi.h"
+#include "base/third_party/nss/sha256.h"
+#include "net/base/base64.h"
#include "net/base/net_util.h"
#include "chrome/common/extensions/extension_error_reporter.h"
#include "chrome/common/extensions/extension_error_utils.h"
@@ -33,6 +37,8 @@ namespace {
const int kRSAKeySize = 1024;
};
+int Extension::id_counter_ = 0;
+
const char Extension::kManifestFilename[] = "manifest.json";
const wchar_t* Extension::kBackgroundKey = L"background_page";
@@ -40,10 +46,10 @@ const wchar_t* Extension::kContentScriptsKey = L"content_scripts";
const wchar_t* Extension::kCssKey = L"css";
const wchar_t* Extension::kDescriptionKey = L"description";
const wchar_t* Extension::kIconPathKey = L"icon";
-const wchar_t* Extension::kIdKey = L"id";
const wchar_t* Extension::kJsKey = L"js";
const wchar_t* Extension::kMatchesKey = L"matches";
const wchar_t* Extension::kNameKey = L"name";
+const wchar_t* Extension::kPageActionIdKey = L"id";
const wchar_t* Extension::kPageActionsKey = L"page_actions";
const wchar_t* Extension::kPermissionsKey = L"permissions";
const wchar_t* Extension::kPluginsKey = L"plugins";
@@ -71,7 +77,6 @@ const char* Extension::kPageActionTypePermanent = "permanent";
static const wchar_t* kValidThemeKeys[] = {
Extension::kDescriptionKey,
Extension::kIconPathKey,
- Extension::kIdKey,
Extension::kNameKey,
Extension::kPublicKeyKey,
Extension::kSignatureKey,
@@ -93,12 +98,12 @@ const char* Extension::kInvalidCssListError =
"Required value 'content_scripts[*].css is invalid.";
const char* Extension::kInvalidDescriptionError =
"Invalid value for 'description'.";
-const char* Extension::kInvalidIdError =
- "Required value 'id' is missing or invalid.";
const char* Extension::kInvalidJsError =
"Invalid value for 'content_scripts[*].js[*]'.";
const char* Extension::kInvalidJsListError =
"Required value 'content_scripts[*].js is invalid.";
+const char* Extension::kInvalidKeyError =
+ "Value 'key' is missing or invalid.";
const char* Extension::kInvalidManifestError =
"Manifest is missing or invalid.";
const char* Extension::kInvalidMatchCountError =
@@ -116,6 +121,8 @@ const char* Extension::kInvalidPageActionsListError =
"Invalid value for 'page_actions'.";
const char* Extension::kInvalidPageActionIconPathError =
"Invalid value for 'page_actions[*].icon'.";
+const char* Extension::kInvalidPageActionIdError =
+ "Required value 'id' is missing or invalid.";
const char* Extension::kInvalidPageActionTooltipError =
"Invalid value for 'page_actions[*].tooltip'.";
const char* Extension::kInvalidPageActionTypeValueError =
@@ -139,6 +146,8 @@ const char* Extension::kInvalidBackgroundError =
"Invalid value for 'background'.";
const char* Extension::kInvalidRunAtError =
"Invalid value for 'content_scripts[*].run_at'.";
+const char* Extension::kInvalidSignatureError =
+ "Value 'signature' is missing or invalid.";
const char* Extension::kInvalidToolstripError =
"Invalid value for 'toolstrips[*]'";
const char* Extension::kInvalidToolstripsError =
@@ -167,7 +176,8 @@ const char* Extension::kExtensionRegistryPath =
"Software\\Google\\Chrome\\Extensions";
#endif
-const size_t Extension::kIdSize = 20; // SHA1 (160 bits) == 20 bytes
+// first 20 bytes of SHA256 hashed public key.
+const size_t Extension::kIdSize = 20;
Extension::~Extension() {
for (PageActionMap::iterator i = page_actions_.begin();
@@ -230,6 +240,23 @@ Extension::Location Extension::ExternalExtensionInstallType(
return Extension::EXTERNAL_PREF;
}
+bool Extension::GenerateIdFromPublicKey(const std::string& input,
+ std::string* output) {
+ CHECK(output);
+ if (input.length() == 0)
+ return false;
+
+ const uint8* ubuf = reinterpret_cast<const unsigned char*>(input.data());
+ SHA256Context ctx;
+ SHA256_Begin(&ctx);
+ SHA256_Update(&ctx, ubuf, input.length());
+ uint8 hash[Extension::kIdSize];
+ SHA256_End(&ctx, hash, NULL, sizeof(hash));
+ *output = StringToLowerASCII(HexEncode(hash, sizeof(hash)));
+
+ return true;
+}
+
// Helper method that loads a UserScript object from a dictionary in the
// content_script list of the manifest.
bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script,
@@ -367,8 +394,8 @@ PageAction* Extension::LoadPageActionHelper(
// Read the page action |id|.
std::string id;
- if (!page_action->GetString(kIdKey, &id)) {
- *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidIdError,
+ if (!page_action->GetString(kPageActionIdKey, &id)) {
+ *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidPageActionIdError,
IntToString(definition_index));
return NULL;
}
@@ -492,13 +519,14 @@ Extension::Extension(const FilePath& path) {
#endif
}
-
// TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a
// util class in base:
// http://code.google.com/p/chromium/issues/detail?id=13572
bool Extension::ParsePEMKeyBytes(const std::string& input,
std::string* output) {
- CHECK(output);
+ DCHECK(output);
+ if (!output)
+ return false;
if (input.length() == 0)
return false;
@@ -564,33 +592,23 @@ bool Extension::FormatPEMForFileOutput(const std::string input,
bool Extension::InitFromValue(const DictionaryValue& source, bool require_id,
std::string* error) {
- // Initialize id.
- if (source.HasKey(kIdKey)) {
- if (!source.GetString(kIdKey, &id_)) {
- *error = kInvalidIdError;
- return false;
- }
-
- // Normalize the string to lowercase, so it can be used as an URL component
- // (where GURL will lowercase it).
- StringToLowerASCII(&id_);
-
- // Verify that the id is legal.
- if (!IdIsValid(id_)) {
- *error = kInvalidIdError;
- return false;
+ if (source.HasKey(kPublicKeyKey)) {
+ std::string public_key_bytes;
+ if (!source.GetString(kPublicKeyKey, &public_key_) ||
+ !ParsePEMKeyBytes(public_key_, &public_key_bytes) ||
+ !GenerateIdFromPublicKey(public_key_bytes, &id_)) {
+ *error = kInvalidKeyError;
+ return false;
}
} else if (require_id) {
- *error = kInvalidIdError;
+ *error = kInvalidKeyError;
return false;
} else {
// Generate a random ID
- static int counter = 0;
- id_ = StringPrintf("%x", counter);
- ++counter;
+ id_ = StringPrintf("%x", NextGeneratedId());
- // pad the string out to 40 chars with zeroes.
- id_.insert(0, 40 - id_.length(), '0');
+ // pad the string out to kIdSize*2 chars with zeroes.
+ id_.insert(0, Extension::kIdSize*2 - id_.length(), '0');
}
// Initialize the URL.
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 9a5bfbf..658b57f 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -38,6 +38,13 @@ class Extension {
KILLBIT, // Don't install/upgrade (applies to external extensions only).
};
+ enum InstallType {
+ DOWNGRADE,
+ REINSTALL,
+ UPGRADE,
+ NEW_INSTALL
+ };
+
// An NPAPI plugin included in the extension.
struct PluginInfo {
FilePath path; // Path to the plugin.
@@ -53,10 +60,10 @@ class Extension {
static const wchar_t* kCssKey;
static const wchar_t* kDescriptionKey;
static const wchar_t* kIconPathKey;
- static const wchar_t* kIdKey;
static const wchar_t* kJsKey;
static const wchar_t* kMatchesKey;
static const wchar_t* kNameKey;
+ static const wchar_t* kPageActionIdKey;
static const wchar_t* kPageActionsKey;
static const wchar_t* kPermissionsKey;
static const wchar_t* kPluginsKey;
@@ -87,9 +94,9 @@ class Extension {
static const char* kInvalidCssError;
static const char* kInvalidCssListError;
static const char* kInvalidDescriptionError;
- static const char* kInvalidIdError;
static const char* kInvalidJsError;
static const char* kInvalidJsListError;
+ static const char* kInvalidKeyError;
static const char* kInvalidManifestError;
static const char* kInvalidMatchCountError;
static const char* kInvalidMatchError;
@@ -101,12 +108,14 @@ class Extension {
static const char* kInvalidBackgroundError;
static const char* kInvalidRunAtError;
+ static const char* kInvalidSignatureError;
static const char* kInvalidToolstripError;
static const char* kInvalidToolstripsError;
static const char* kInvalidVersionError;
static const char* kInvalidPageActionError;
static const char* kInvalidPageActionsListError;
static const char* kInvalidPageActionIconPathError;
+ static const char* kInvalidPageActionIdError;
static const char* kInvalidPageActionTooltipError;
static const char* kInvalidPageActionTypeValueError;
static const char* kInvalidPermissionsError;
@@ -133,6 +142,11 @@ class Extension {
explicit Extension(const FilePath& path);
virtual ~Extension();
+ // Resets the id counter. This is only useful for unit tests.
+ static void ResetGeneratedIdCounter() {
+ id_counter_ = 0;
+ }
+
// Checks to see if the extension has a valid ID.
static bool IdIsValid(const std::string& id);
@@ -173,6 +187,11 @@ class Extension {
// Does a simple base64 encoding of |input| into |output|.
static bool ProducePEM(const std::string& input, std::string* output);
+ // Note: The result is coverted to lower-case because the browser enforces
+ // hosts to be lower-case in omni-bar.
+ static bool GenerateIdFromPublicKey(const std::string& input,
+ std::string* output);
+
// Expects base64 encoded |input| and formats into |output| including
// the appropriate header & footer.
static bool FormatPEMForFileOutput(const std::string input,
@@ -193,6 +212,7 @@ class Extension {
// String representation of the version number.
const std::string VersionString() const;
const std::string& name() const { return name_; }
+ const std::string& public_key() const { return public_key_; }
const std::string& description() const { return description_; }
const UserScriptList& content_scripts() const { return content_scripts_; }
const PageActionMap& page_actions() const { return page_actions_; }
@@ -222,6 +242,14 @@ class Extension {
std::set<FilePath> GetBrowserImages();
private:
+ // Counter used to assign ids to extensions that are loaded using
+ // --load-extension.
+ static int id_counter_;
+
+ // Returns the next counter id. Intentionally post-incrementing so that first
+ // value is 0.
+ static int NextGeneratedId() { return id_counter_++; }
+
// Helper method that loads a UserScript object from a
// dictionary in the content_script list of the manifest.
bool LoadUserScriptHelper(const DictionaryValue* content_script,
@@ -281,10 +309,9 @@ class Extension {
// Paths to HTML files to be displayed in the toolbar.
std::vector<std::string> toolstrips_;
- // A SHA1 hash of the contents of the zip file. Note that this key is only
- // present in the manifest that's prepended to the zip. The inner manifest
- // will not have this key.
- std::string zip_hash_;
+ // The public key ('key' in the manifest) used to sign the contents of the
+ // crx package ('signature' in the manifest)
+ std::string public_key_;
// A map of resource id's to relative file paths.
scoped_ptr<DictionaryValue> theme_images_;
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc
index 7f0f288..661bcb6 100644
--- a/chrome/common/extensions/extension_unittest.cc
+++ b/chrome/common/extensions/extension_unittest.cc
@@ -43,17 +43,6 @@ TEST(ExtensionTest, InitFromValueInvalid) {
scoped_ptr<DictionaryValue> input_value;
- // Test missing and invalid ids
- input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
- input_value->Remove(Extension::kIdKey, NULL);
- EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
- EXPECT_EQ(Extension::kInvalidIdError, error);
-
- input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
- input_value->SetInteger(Extension::kIdKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
- EXPECT_EQ(Extension::kInvalidIdError, error);
-
// Test missing and invalid versions
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->Remove(Extension::kVersionKey, NULL);
@@ -204,22 +193,22 @@ TEST(ExtensionTest, InitFromValueValid) {
#elif defined(OS_POSIX)
FilePath path(FILE_PATH_LITERAL("/foo"));
#endif
+ Extension::ResetGeneratedIdCounter();
+
Extension extension(path);
std::string error;
DictionaryValue input_value;
// Test minimal extension
- input_value.SetString(Extension::kIdKey,
- "00123456789ABCDEF0123456789ABCDEF0123456");
input_value.SetString(Extension::kVersionKey, "1.0.0.0");
input_value.SetString(Extension::kNameKey, "my extension");
- EXPECT_TRUE(extension.InitFromValue(input_value, true, &error));
+ EXPECT_TRUE(extension.InitFromValue(input_value, false, &error));
EXPECT_EQ("", error);
- EXPECT_EQ("00123456789abcdef0123456789abcdef0123456", extension.id());
+ EXPECT_EQ("0000000000000000000000000000000000000000", extension.id());
EXPECT_EQ("1.0.0.0", extension.VersionString());
EXPECT_EQ("my extension", extension.name());
- EXPECT_EQ("chrome-extension://00123456789abcdef0123456789abcdef0123456/",
+ EXPECT_EQ("chrome-extension://0000000000000000000000000000000000000000/",
extension.url().spec());
EXPECT_EQ(path.value(), extension.path().value());
}
@@ -232,11 +221,9 @@ TEST(ExtensionTest, GetResourceURLAndPath) {
#endif
Extension extension(path);
DictionaryValue input_value;
- input_value.SetString(Extension::kIdKey,
- "00123456789ABCDEF0123456789ABCDEF0123456");
input_value.SetString(Extension::kVersionKey, "1.0.0.0");
input_value.SetString(Extension::kNameKey, "my extension");
- EXPECT_TRUE(extension.InitFromValue(input_value, true, NULL));
+ EXPECT_TRUE(extension.InitFromValue(input_value, false, NULL));
EXPECT_EQ(extension.url().spec() + "bar/baz.js",
Extension::GetResourceURL(extension.url(), "bar/baz.js").spec());
diff --git a/chrome/common/extensions/extension_unpacker.cc b/chrome/common/extensions/extension_unpacker.cc
index b5bc919..bae5a7d 100644
--- a/chrome/common/extensions/extension_unpacker.cc
+++ b/chrome/common/extensions/extension_unpacker.cc
@@ -8,8 +8,6 @@
#include "base/scoped_handle.h"
#include "base/scoped_temp_dir.h"
#include "base/string_util.h"
-#include "base/third_party/nss/blapi.h"
-#include "base/third_party/nss/sha256.h"
#include "base/thread.h"
#include "base/values.h"
#include "net/base/file_stream.h"
@@ -23,8 +21,6 @@
#include "webkit/glue/image_decoder.h"
namespace {
-const char kCurrentVersionFileName[] = "Current Version";
-
// The name of a temporary directory to install an extension into for
// validation before finalizing install.
const char kTempExtensionName[] = "TEMP_INSTALL";
@@ -32,27 +28,14 @@ const char kTempExtensionName[] = "TEMP_INSTALL";
// The file to write our decoded images to, relative to the extension_path.
const char kDecodedImagesFilename[] = "DECODED_IMAGES";
-// Chromium Extension magic number
-// TODO(aa): This should use the one in ExtensionCreator once we transition this
-// to ouptut the same format.
-const char kExtensionFileMagic[] = "Cr24";
-
-struct ExtensionHeader {
- char magic[sizeof(kExtensionFileMagic) - 1];
- uint32 version;
- size_t header_size;
- size_t manifest_size;
-};
-
-const size_t kZipHashBytes = 32; // SHA-256
-const size_t kZipHashHexBytes = kZipHashBytes * 2; // Hex string is 2x size.
+// Errors
+const char* kCouldNotCreateDirectoryError =
+ "Could not create directory for unzipping.";
+const char* kCouldNotDecodeImageError = "Could not decode theme image.";
+const char* kCouldNotUnzipExtension = "Could not unzip extension.";
+const char* kPathNamesMustBeAbsoluteOrLocalError =
+ "Path names must not be absolute or contain '..'.";
-// A marker file to indicate that an extension was installed from an external
-// source.
-const char kExternalInstallFile[] = "EXTERNAL_INSTALL";
-
-// The version of the extension package that this code understands.
-const uint32 kExpectedVersion = 1;
} // namespace
static SkBitmap DecodeImage(const FilePath& path) {
@@ -90,74 +73,6 @@ static bool PathContainsParentDirectory(const FilePath& path) {
return false;
}
-// The extension file format is a header, followed by the manifest, followed
-// by the zip file. The header is a magic number, a version, the size of the
-// header, and the size of the manifest. These ints are 4 byte little endian.
-DictionaryValue* ExtensionUnpacker::ReadPackageHeader() {
- ScopedStdioHandle file(file_util::OpenFile(extension_path_, "rb"));
- if (!file.get()) {
- SetError("no such extension file");
- return NULL;
- }
-
- // Read and verify the header.
- ExtensionHeader header;
- size_t len;
-
- // TODO(erikkay): Yuck. I'm not a big fan of this kind of code, but it
- // appears that we don't have any endian/alignment aware serialization
- // code in the code base. So for now, this assumes that we're running
- // on a little endian machine with 4 byte alignment.
- len = fread(&header, 1, sizeof(ExtensionHeader), file.get());
- if (len < sizeof(ExtensionHeader)) {
- SetError("invalid extension header");
- return NULL;
- }
- if (strncmp(kExtensionFileMagic, header.magic, sizeof(header.magic))) {
- SetError("bad magic number");
- return NULL;
- }
- if (header.version != kExpectedVersion) {
- SetError("bad version number");
- return NULL;
- }
- if (header.header_size > sizeof(ExtensionHeader))
- fseek(file.get(), header.header_size - sizeof(ExtensionHeader), SEEK_CUR);
-
- char buf[1 << 16];
- std::string manifest_str;
- size_t read_size = std::min(sizeof(buf), header.manifest_size);
- size_t remainder = header.manifest_size;
- while ((len = fread(buf, 1, read_size, file.get())) > 0) {
- manifest_str.append(buf, len);
- if (len <= remainder)
- break;
- remainder -= len;
- read_size = std::min(sizeof(buf), remainder);
- }
-
- // Verify the JSON
- JSONStringValueSerializer json(manifest_str);
- std::string error;
- scoped_ptr<Value> val(json.Deserialize(&error));
- if (!val.get()) {
- SetError(error);
- return NULL;
- }
- if (!val->IsType(Value::TYPE_DICTIONARY)) {
- SetError("manifest isn't a JSON dictionary");
- return NULL;
- }
- DictionaryValue* manifest = static_cast<DictionaryValue*>(val.get());
-
- // TODO(erikkay): The manifest will also contain a signature of the hash
- // (or perhaps the whole manifest) for authentication purposes.
-
- // The caller owns val (now cast to manifest).
- val.release();
- return manifest;
-}
-
DictionaryValue* ExtensionUnpacker::ReadManifest() {
FilePath manifest_path =
temp_install_dir_.AppendASCII(Extension::kManifestFilename);
@@ -185,34 +100,16 @@ DictionaryValue* ExtensionUnpacker::ReadManifest() {
bool ExtensionUnpacker::Run() {
LOG(INFO) << "Installing extension " << extension_path_.value();
- // Read and verify the extension.
- scoped_ptr<DictionaryValue> header_manifest(ReadPackageHeader());
- if (!header_manifest.get()) {
- // ReadPackageHeader has already reported the extension error.
- return false;
- }
-
- // TODO(mpcomplete): it looks like this isn't actually necessary. We don't
- // use header_extension, and we check that the unzipped manifest is valid.
- Extension header_extension;
- std::string error;
- if (!header_extension.InitFromValue(*header_manifest,
- true, // require ID
- &error)) {
- SetError(error);
- return false;
- }
-
// <profile>/Extensions/INSTALL_TEMP/<version>
temp_install_dir_ =
extension_path_.DirName().AppendASCII(kTempExtensionName);
if (!file_util::CreateDirectory(temp_install_dir_)) {
- SetError("Couldn't create directory for unzipping.");
+ SetError(kCouldNotCreateDirectoryError);
return false;
}
if (!Unzip(extension_path_, temp_install_dir_)) {
- SetError("Couldn't unzip extension.");
+ SetError(kCouldNotUnzipExtension);
return false;
}
@@ -220,16 +117,19 @@ bool ExtensionUnpacker::Run() {
parsed_manifest_.reset(ReadManifest());
if (!parsed_manifest_.get())
return false; // Error was already reported.
-
- // Re-read the actual manifest into our extension struct.
+
+ // NOTE: Since the Unpacker doesn't have the extension's public_id, the
+ // InitFromValue is allowed to generate a temporary id for the extension.
+ // ANY CODE THAT FOLLOWS SHOULD NOT DEPEND ON THE CORRECT ID OF THIS
+ // EXTENSION.
Extension extension;
+ std::string error;
if (!extension.InitFromValue(*parsed_manifest_,
- true, // require ID
+ false,
&error)) {
SetError(error);
return false;
}
-
// Decode any images that the browser needs to display.
std::set<FilePath> image_paths = extension.GetBrowserImages();
for (std::set<FilePath>::iterator it = image_paths.begin();
@@ -271,13 +171,13 @@ bool ExtensionUnpacker::ReadImagesFromFile(const FilePath& extension_path,
bool ExtensionUnpacker::AddDecodedImage(const FilePath& path) {
// Make sure it's not referencing a file outside the extension's subdir.
if (path.IsAbsolute() || PathContainsParentDirectory(path)) {
- SetError("Path names must not be absolute or contain '..'.");
+ SetError(kPathNamesMustBeAbsoluteOrLocalError);
return false;
}
SkBitmap image_bitmap = DecodeImage(temp_install_dir_.Append(path));
if (image_bitmap.isNull()) {
- SetError("Could not decode theme image.");
+ SetError(kCouldNotDecodeImageError);
return false;
}
diff --git a/chrome/common/extensions/extension_unpacker.h b/chrome/common/extensions/extension_unpacker.h
index 65af750..aeb72d9 100644
--- a/chrome/common/extensions/extension_unpacker.h
+++ b/chrome/common/extensions/extension_unpacker.h
@@ -48,10 +48,6 @@ class ExtensionUnpacker {
const DecodedImages& decoded_images() { return decoded_images_; }
private:
- // Parse the header on the front of the extension file and return the manifest
- // inside it. Caller takes ownership of return value.
- DictionaryValue* ReadPackageHeader();
-
// Parse the manifest.json file inside the extension (not in the header).
// Caller takes ownership of return value.
DictionaryValue* ReadManifest();