Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: extensions/browser/content_verify_job.cc

Issue 329303007: Fix several problems with the content verification code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ready Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/browser/content_verify_job.h" 5 #include "extensions/browser/content_verify_job.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/task_runner_util.h" 10 #include "base/task_runner_util.h"
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 DCHECK(thread_checker_.CalledOnValidThread()); 42 DCHECK(thread_checker_.CalledOnValidThread());
43 base::PostTaskAndReplyWithResult( 43 base::PostTaskAndReplyWithResult(
44 content::BrowserThread::GetBlockingPool(), 44 content::BrowserThread::GetBlockingPool(),
45 FROM_HERE, 45 FROM_HERE,
46 base::Bind(&ContentHashReader::Init, hash_reader_), 46 base::Bind(&ContentHashReader::Init, hash_reader_),
47 base::Bind(&ContentVerifyJob::OnHashesReady, this)); 47 base::Bind(&ContentVerifyJob::OnHashesReady, this));
48 } 48 }
49 49
50 void ContentVerifyJob::BytesRead(int count, const char* data) { 50 void ContentVerifyJob::BytesRead(int count, const char* data) {
51 DCHECK(thread_checker_.CalledOnValidThread()); 51 DCHECK(thread_checker_.CalledOnValidThread());
52 if (failure_callback_.is_null())
Ken Rockot(use gerrit already) 2014/06/17 16:43:43 I think it would be easier to understand if you ju
asargent_no_longer_on_chrome 2014/06/18 00:13:51 Good suggestion. Done.
53 return;
52 if (g_test_delegate) { 54 if (g_test_delegate) {
53 FailureReason reason = 55 FailureReason reason =
54 g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data); 56 g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data);
55 if (reason != NONE) 57 if (reason != NONE)
56 return DispatchFailureCallback(reason); 58 return DispatchFailureCallback(reason);
57 } 59 }
58 if (!hashes_ready_) { 60 if (!hashes_ready_) {
59 queue_.append(data, count); 61 queue_.append(data, count);
60 return; 62 return;
61 } 63 }
62 DCHECK_GE(count, 0); 64 DCHECK_GE(count, 0);
63 int bytes_added = 0; 65 int bytes_added = 0;
64 66
65 while (bytes_added < count) { 67 while (bytes_added < count) {
68 if (failure_callback_.is_null())
Ken Rockot(use gerrit already) 2014/06/17 16:43:43 In this specific case, if FinishBlock() is the onl
69 return;
70
66 if (current_block_ >= hash_reader_->block_count()) 71 if (current_block_ >= hash_reader_->block_count())
67 return DispatchFailureCallback(HASH_MISMATCH); 72 return DispatchFailureCallback(HASH_MISMATCH);
68 73
69 if (!current_hash_.get()) { 74 if (!current_hash_.get()) {
70 current_hash_byte_count_ = 0; 75 current_hash_byte_count_ = 0;
71 current_hash_.reset( 76 current_hash_.reset(
72 crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 77 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
73 } 78 }
74 // Compute how many bytes we should hash, and add them to the current hash. 79 // Compute how many bytes we should hash, and add them to the current hash.
75 int bytes_to_hash = 80 int bytes_to_hash =
76 std::min(hash_reader_->block_size() - current_hash_byte_count_, 81 std::min(hash_reader_->block_size() - current_hash_byte_count_,
77 count - bytes_added); 82 count - bytes_added);
83 DCHECK(bytes_to_hash > 0);
78 current_hash_->Update(data + bytes_added, bytes_to_hash); 84 current_hash_->Update(data + bytes_added, bytes_to_hash);
79 bytes_added += bytes_to_hash; 85 bytes_added += bytes_to_hash;
80 current_hash_byte_count_ += bytes_to_hash; 86 current_hash_byte_count_ += bytes_to_hash;
81 total_bytes_read_ += bytes_to_hash; 87 total_bytes_read_ += bytes_to_hash;
82 88
83 // If we finished reading a block worth of data, finish computing the hash 89 // If we finished reading a block worth of data, finish computing the hash
84 // for it and make sure the expected hash matches. 90 // for it and make sure the expected hash matches.
85 if (current_hash_byte_count_ == hash_reader_->block_size()) 91 if (current_hash_byte_count_ == hash_reader_->block_size())
86 FinishBlock(); 92 FinishBlock();
87 } 93 }
88 } 94 }
89 95
90 void ContentVerifyJob::DoneReading() { 96 void ContentVerifyJob::DoneReading() {
91 DCHECK(thread_checker_.CalledOnValidThread()); 97 DCHECK(thread_checker_.CalledOnValidThread());
98 if (failure_callback_.is_null())
99 return;
92 if (g_test_delegate) { 100 if (g_test_delegate) {
93 FailureReason reason = 101 FailureReason reason =
94 g_test_delegate->DoneReading(hash_reader_->extension_id()); 102 g_test_delegate->DoneReading(hash_reader_->extension_id());
95 if (reason != NONE) { 103 if (reason != NONE) {
96 DispatchFailureCallback(reason); 104 DispatchFailureCallback(reason);
97 return; 105 return;
98 } 106 }
99 } 107 }
100 done_reading_ = true; 108 done_reading_ = true;
101 if (hashes_ready_) 109 if (hashes_ready_)
102 FinishBlock(); 110 FinishBlock();
103 } 111 }
104 112
105 void ContentVerifyJob::FinishBlock() { 113 void ContentVerifyJob::FinishBlock() {
106 if (current_hash_byte_count_ <= 0) 114 if (current_hash_byte_count_ <= 0)
107 return; 115 return;
108 std::string final(crypto::kSHA256Length, 0); 116 std::string final(crypto::kSHA256Length, 0);
109 current_hash_->Finish(string_as_array(&final), final.size()); 117 current_hash_->Finish(string_as_array(&final), final.size());
110 118
111 const std::string* expected_hash = NULL; 119 const std::string* expected_hash = NULL;
112 if (!hash_reader_->GetHashForBlock(current_block_, &expected_hash)) 120 if (!hash_reader_->GetHashForBlock(current_block_, &expected_hash) ||
113 return DispatchFailureCallback(HASH_MISMATCH); 121 *expected_hash != final)
114 122 DispatchFailureCallback(HASH_MISMATCH);
115 if (*expected_hash != final)
116 return DispatchFailureCallback(HASH_MISMATCH);
117 123
118 current_hash_.reset(); 124 current_hash_.reset();
119 current_hash_byte_count_ = 0; 125 current_hash_byte_count_ = 0;
120 current_block_++; 126 current_block_++;
121 } 127 }
122 128
123 void ContentVerifyJob::OnHashesReady(bool success) { 129 void ContentVerifyJob::OnHashesReady(bool success) {
124 if (!success && !g_test_delegate) 130 if (!success && !g_test_delegate) {
125 return DispatchFailureCallback(NO_HASHES); 131 if (hash_reader_->have_verified_contents() &&
132 hash_reader_->have_computed_hashes())
133 DispatchFailureCallback(NO_HASHES_FOR_FILE);
134 else
135 DispatchFailureCallback(MISSING_ALL_HASHES);
136 return;
137 }
126 138
127 hashes_ready_ = true; 139 hashes_ready_ = true;
128 if (!queue_.empty()) { 140 if (!queue_.empty()) {
129 std::string tmp; 141 std::string tmp;
130 queue_.swap(tmp); 142 queue_.swap(tmp);
131 BytesRead(tmp.size(), string_as_array(&tmp)); 143 BytesRead(tmp.size(), string_as_array(&tmp));
132 } 144 }
133 if (done_reading_) 145 if (done_reading_)
134 FinishBlock(); 146 FinishBlock();
135 } 147 }
136 148
137 // static 149 // static
138 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) { 150 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) {
139 g_test_delegate = delegate; 151 g_test_delegate = delegate;
140 } 152 }
141 153
142 void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) { 154 void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
143 if (!failure_callback_.is_null()) { 155 if (!failure_callback_.is_null()) {
156 VLOG(1) << "job failed for " << hash_reader_->extension_id() << " "
157 << hash_reader_->relative_path().MaybeAsASCII()
158 << " reason:" << reason;
144 failure_callback_.Run(reason); 159 failure_callback_.Run(reason);
145 failure_callback_.Reset(); 160 failure_callback_.Reset();
146 } 161 }
147 } 162 }
148 163
149 } // namespace extensions 164 } // namespace extensions
OLDNEW
« extensions/browser/content_hash_fetcher.cc ('K') | « extensions/browser/content_verify_job.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698