| Index: chrome/browser/component_updater/component_unpacker.cc
|
| diff --git a/chrome/browser/component_updater/component_unpacker.cc b/chrome/browser/component_updater/component_unpacker.cc
|
| index ed7bf1fc02a9d3bb3e0f0ec0e3748a2a93eb97e0..7537f01e873c53bc286a9eddc4e1a9b564a98ef5 100644
|
| --- a/chrome/browser/component_updater/component_unpacker.cc
|
| +++ b/chrome/browser/component_updater/component_unpacker.cc
|
| @@ -31,6 +31,15 @@ namespace component_updater {
|
|
|
| namespace {
|
|
|
| +const char kKeyNameFingerprint[] = "fingerprint";
|
| +const char kKeyNamePublicKeyHash[] = "public_key_hash";
|
| +const char kKeyNameInProcess[] = "in_process";
|
| +
|
| +const base::FilePath::CharType kCrxFileName[] =
|
| + FILE_PATH_LITERAL("saved_installer.crx");
|
| +const base::FilePath::CharType kInstallDataFileName[] =
|
| + FILE_PATH_LITERAL("metadata.json");
|
| +
|
| // This class makes sure that the CRX digital signature is valid
|
| // and well formed.
|
| class CRXValidator {
|
| @@ -124,8 +133,7 @@ scoped_ptr<base::DictionaryValue> ReadManifest(
|
| if (!base::PathExists(manifest))
|
| return scoped_ptr<base::DictionaryValue>();
|
| JSONFileValueSerializer serializer(manifest);
|
| - std::string error;
|
| - scoped_ptr<base::Value> root(serializer.Deserialize(NULL, &error));
|
| + scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
|
| if (!root.get())
|
| return scoped_ptr<base::DictionaryValue>();
|
| if (!root->IsType(base::Value::TYPE_DICTIONARY))
|
| @@ -264,6 +272,8 @@ void ComponentUnpacker::Install() {
|
| }
|
| DCHECK(error_ == kNone);
|
| if (!installer_->Install(*manifest, unpack_path_)) {
|
| + installer_->OnInstallError(
|
| + base::Bind(&ComponentUnpacker::SaveInstallSource, this));
|
| error_ = kInstallerError;
|
| return;
|
| }
|
| @@ -280,4 +290,82 @@ void ComponentUnpacker::Finish() {
|
| ComponentUnpacker::~ComponentUnpacker() {
|
| }
|
|
|
| +bool ComponentUnpacker::SaveInstallSource(
|
| + const base::FilePath& backup_path) const {
|
| + if (!base::CreateDirectory(backup_path)) {
|
| + return false;
|
| + }
|
| +
|
| + const base::FilePath crx_path = backup_path.Append(kCrxFileName);
|
| + if (!base::CopyFile(path_, crx_path)) {
|
| + return false;
|
| + }
|
| +
|
| + const base::FilePath install_data_file_path =
|
| + backup_path.Append(kInstallDataFileName);
|
| + JSONFileValueSerializer serializer(install_data_file_path);
|
| +
|
| + scoped_ptr<base::DictionaryValue> root(new base::DictionaryValue);
|
| + root->SetString(kKeyNameFingerprint, fingerprint_);
|
| + root->SetBoolean(kKeyNameInProcess, in_process_);
|
| + scoped_ptr<base::ListValue> pk_hash_list_value(new base::ListValue);
|
| + for (size_t i = 0; i < pk_hash_.size(); ++i) {
|
| + pk_hash_list_value->Append(base::Value::CreateIntegerValue(
|
| + static_cast<int>(pk_hash_[i])));
|
| + }
|
| + root->Set(kKeyNamePublicKeyHash, pk_hash_list_value.release());
|
| + if (!serializer.Serialize(*root)) {
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +scoped_refptr<ComponentUnpacker> ComponentUnpacker::CreateFromBackup(
|
| + const base::FilePath& backup_path,
|
| + ComponentInstaller* installer,
|
| + scoped_refptr<base::SequencedTaskRunner> task_runner) {
|
| + const base::FilePath crx_path = backup_path.Append(kCrxFileName);
|
| + if (!base::PathExists(crx_path) || base::DirectoryExists(crx_path)) {
|
| + return scoped_refptr<ComponentUnpacker>();
|
| + }
|
| +
|
| + std::string fingerprint;
|
| + bool in_process = false;
|
| +
|
| + const base::FilePath install_data_file_path =
|
| + backup_path.Append(kInstallDataFileName);
|
| + if (!base::PathExists(install_data_file_path)) {
|
| + return scoped_refptr<ComponentUnpacker>();
|
| + }
|
| +
|
| + JSONFileValueSerializer serializer(install_data_file_path);
|
| + scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
|
| + if (!root.get() || !root->IsType(base::Value::TYPE_DICTIONARY)) {
|
| + return scoped_refptr<ComponentUnpacker>();
|
| + }
|
| +
|
| + scoped_ptr<base::DictionaryValue> install_metadata(
|
| + static_cast<base::DictionaryValue*>(root.release()));
|
| +
|
| + base::ListValue* pk_hash_list_value = NULL;
|
| + if (!install_metadata->GetStringASCII(kKeyNameFingerprint, &fingerprint) ||
|
| + !install_metadata->GetBoolean(kKeyNameInProcess, &in_process) ||
|
| + !install_metadata->GetList(kKeyNamePublicKeyHash, &pk_hash_list_value) ||
|
| + pk_hash_list_value == NULL) {
|
| + return scoped_refptr<ComponentUnpacker>();
|
| + }
|
| +
|
| + std::vector<uint8> pk_hash;
|
| + for (size_t i = 0; i < pk_hash_list_value->GetSize(); ++i) {
|
| + int value = 0;
|
| + if (pk_hash_list_value->GetInteger(i, &value)) {
|
| + pk_hash.push_back(static_cast<uint8>(value));
|
| + }
|
| + }
|
| +
|
| + return make_scoped_refptr(new ComponentUnpacker(
|
| + pk_hash, crx_path, fingerprint, installer, in_process, task_runner));
|
| +}
|
| +
|
| } // namespace component_updater
|
|
|