Index: extensions/browser/content_verify_job.cc |
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc |
index 5eec659d331fc24881aeedfe8dc2b5101f96cd0b..e3e35506718441ec9f815f1269efe4b4043d4a27 100644 |
--- a/extensions/browser/content_verify_job.cc |
+++ b/extensions/browser/content_verify_job.cc |
@@ -29,7 +29,8 @@ ContentVerifyJob::ContentVerifyJob(ContentHashReader* hash_reader, |
current_block_(0), |
current_hash_byte_count_(0), |
hash_reader_(hash_reader), |
- failure_callback_(failure_callback) { |
+ failure_callback_(failure_callback), |
+ failed_(false) { |
// It's ok for this object to be constructed on a different thread from where |
// it's used. |
thread_checker_.DetachFromThread(); |
@@ -49,6 +50,8 @@ void ContentVerifyJob::Start() { |
void ContentVerifyJob::BytesRead(int count, const char* data) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (failed_) |
+ return; |
if (g_test_delegate) { |
FailureReason reason = |
g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data); |
@@ -75,6 +78,7 @@ void ContentVerifyJob::BytesRead(int count, const char* data) { |
int bytes_to_hash = |
std::min(hash_reader_->block_size() - current_hash_byte_count_, |
count - bytes_added); |
+ DCHECK(bytes_to_hash > 0); |
current_hash_->Update(data + bytes_added, bytes_to_hash); |
bytes_added += bytes_to_hash; |
current_hash_byte_count_ += bytes_to_hash; |
@@ -82,13 +86,18 @@ void ContentVerifyJob::BytesRead(int count, const char* data) { |
// If we finished reading a block worth of data, finish computing the hash |
// for it and make sure the expected hash matches. |
- if (current_hash_byte_count_ == hash_reader_->block_size()) |
- FinishBlock(); |
+ if (current_hash_byte_count_ == hash_reader_->block_size() && |
+ !FinishBlock()) { |
+ DispatchFailureCallback(HASH_MISMATCH); |
+ return; |
+ } |
} |
} |
void ContentVerifyJob::DoneReading() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (failed_) |
+ return; |
if (g_test_delegate) { |
FailureReason reason = |
g_test_delegate->DoneReading(hash_reader_->extension_id()); |
@@ -98,31 +107,36 @@ void ContentVerifyJob::DoneReading() { |
} |
} |
done_reading_ = true; |
- if (hashes_ready_) |
- FinishBlock(); |
+ if (hashes_ready_ && !FinishBlock()) |
+ DispatchFailureCallback(HASH_MISMATCH); |
} |
-void ContentVerifyJob::FinishBlock() { |
+bool ContentVerifyJob::FinishBlock() { |
if (current_hash_byte_count_ <= 0) |
- return; |
+ return true; |
std::string final(crypto::kSHA256Length, 0); |
current_hash_->Finish(string_as_array(&final), final.size()); |
const std::string* expected_hash = NULL; |
- if (!hash_reader_->GetHashForBlock(current_block_, &expected_hash)) |
- return DispatchFailureCallback(HASH_MISMATCH); |
- |
- if (*expected_hash != final) |
- return DispatchFailureCallback(HASH_MISMATCH); |
+ if (!hash_reader_->GetHashForBlock(current_block_, &expected_hash) || |
+ *expected_hash != final) |
+ return false; |
current_hash_.reset(); |
current_hash_byte_count_ = 0; |
current_block_++; |
+ return true; |
} |
void ContentVerifyJob::OnHashesReady(bool success) { |
- if (!success && !g_test_delegate) |
- return DispatchFailureCallback(NO_HASHES); |
+ if (!success && !g_test_delegate) { |
+ if (hash_reader_->have_verified_contents() && |
+ hash_reader_->have_computed_hashes()) |
+ DispatchFailureCallback(NO_HASHES_FOR_FILE); |
+ else |
+ DispatchFailureCallback(MISSING_ALL_HASHES); |
+ return; |
+ } |
hashes_ready_ = true; |
if (!queue_.empty()) { |
@@ -130,8 +144,8 @@ void ContentVerifyJob::OnHashesReady(bool success) { |
queue_.swap(tmp); |
BytesRead(tmp.size(), string_as_array(&tmp)); |
} |
- if (done_reading_) |
- FinishBlock(); |
+ if (done_reading_ && !FinishBlock()) |
+ DispatchFailureCallback(HASH_MISMATCH); |
} |
// static |
@@ -140,7 +154,12 @@ void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) { |
} |
void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) { |
+ DCHECK(!failed_); |
+ failed_ = true; |
if (!failure_callback_.is_null()) { |
+ VLOG(1) << "job failed for " << hash_reader_->extension_id() << " " |
+ << hash_reader_->relative_path().MaybeAsASCII() |
+ << " reason:" << reason; |
failure_callback_.Run(reason); |
failure_callback_.Reset(); |
} |