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

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

Issue 2771953003: Fix content verification code for undreadable and deleted files. (Closed)
Patch Set: address comments change DCHECK Created 3 years, 8 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
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/metrics/histogram_macros.h" 9 #include "base/metrics/histogram_macros.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 return; 127 return;
128 if (g_test_delegate) { 128 if (g_test_delegate) {
129 FailureReason reason = 129 FailureReason reason =
130 g_test_delegate->DoneReading(hash_reader_->extension_id()); 130 g_test_delegate->DoneReading(hash_reader_->extension_id());
131 if (reason != NONE) 131 if (reason != NONE)
132 DispatchFailureCallback(reason); 132 DispatchFailureCallback(reason);
133 return; 133 return;
134 } 134 }
135 done_reading_ = true; 135 done_reading_ = true;
136 if (hashes_ready_) { 136 if (hashes_ready_) {
137 if (!FinishBlock()) 137 if (!FinishBlock()) {
138 DispatchFailureCallback(HASH_MISMATCH); 138 DispatchFailureCallback(HASH_MISMATCH);
139 else if (g_test_observer) 139 } else if (g_test_observer) {
140 g_test_observer->JobFinished(hash_reader_->extension_id(), 140 g_test_observer->JobFinished(hash_reader_->extension_id(),
141 hash_reader_->relative_path(), failed_); 141 hash_reader_->relative_path(), NONE);
142 }
142 } 143 }
143 } 144 }
144 145
145 bool ContentVerifyJob::FinishBlock() { 146 bool ContentVerifyJob::FinishBlock() {
146 if (current_hash_byte_count_ <= 0) 147 if (!done_reading_ && current_hash_byte_count_ == 0)
147 return true; 148 return true;
149 if (!current_hash_) {
150 // This happens when we fail to read the resource. Compute empty content's
151 // hash in this case.
152 current_hash_ = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
153 }
148 std::string final(crypto::kSHA256Length, 0); 154 std::string final(crypto::kSHA256Length, 0);
149 current_hash_->Finish(base::string_as_array(& final), final.size()); 155 current_hash_->Finish(base::string_as_array(& final), final.size());
150 current_hash_.reset(); 156 current_hash_.reset();
151 current_hash_byte_count_ = 0; 157 current_hash_byte_count_ = 0;
152 158
153 int block = current_block_++; 159 int block = current_block_++;
154 160
155 const std::string* expected_hash = NULL; 161 const std::string* expected_hash = NULL;
156 if (!hash_reader_->GetHashForBlock(block, &expected_hash) || 162 if (!hash_reader_->GetHashForBlock(block, &expected_hash) ||
157 *expected_hash != final) 163 *expected_hash != final) {
158 return false; 164 return false;
165 }
159 166
160 return true; 167 return true;
161 } 168 }
162 169
163 void ContentVerifyJob::OnHashesReady(bool success) { 170 void ContentVerifyJob::OnHashesReady(bool success) {
164 if (!success && !g_test_delegate) { 171 if (!success && !g_test_delegate) {
165 if (!hash_reader_->content_exists()) { 172 // TODO(lazyboy): Make ContentHashReader::Init return an enum instead of
173 // bool. This should make the following checks on |hash_reader_| easier
174 // to digest and will avoid future bugs from creeping up.
175 if (!hash_reader_->have_verified_contents() ||
176 !hash_reader_->have_computed_hashes()) {
177 DispatchFailureCallback(MISSING_ALL_HASHES);
178 return;
179 }
180
181 if (hash_reader_->file_missing_from_verified_contents()) {
166 // Ignore verification of non-existent resources. 182 // Ignore verification of non-existent resources.
183 if (g_test_observer) {
184 g_test_observer->JobFinished(hash_reader_->extension_id(),
185 hash_reader_->relative_path(), NONE);
186 }
167 return; 187 return;
168 } else if (hash_reader_->have_verified_contents() &&
169 hash_reader_->have_computed_hashes()) {
170 DispatchFailureCallback(NO_HASHES_FOR_FILE);
171 } else {
172 DispatchFailureCallback(MISSING_ALL_HASHES);
173 } 188 }
189 DispatchFailureCallback(NO_HASHES_FOR_FILE);
174 return; 190 return;
175 } 191 }
176 192
177 hashes_ready_ = true; 193 hashes_ready_ = true;
178 if (!queue_.empty()) { 194 if (!queue_.empty()) {
179 std::string tmp; 195 std::string tmp;
180 queue_.swap(tmp); 196 queue_.swap(tmp);
181 BytesRead(tmp.size(), base::string_as_array(&tmp)); 197 BytesRead(tmp.size(), base::string_as_array(&tmp));
182 } 198 }
183 if (done_reading_) { 199 if (done_reading_) {
184 ScopedElapsedTimer timer(&time_spent_); 200 ScopedElapsedTimer timer(&time_spent_);
185 if (!FinishBlock()) { 201 if (!FinishBlock()) {
186 DispatchFailureCallback(HASH_MISMATCH); 202 DispatchFailureCallback(HASH_MISMATCH);
187 } else if (g_test_observer) { 203 } else if (g_test_observer) {
188 g_test_observer->JobFinished(hash_reader_->extension_id(), 204 g_test_observer->JobFinished(hash_reader_->extension_id(),
189 hash_reader_->relative_path(), failed_); 205 hash_reader_->relative_path(), NONE);
190 } 206 }
191 } 207 }
192 } 208 }
193 209
194 // static 210 // static
195 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) { 211 void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) {
196 DCHECK(delegate == nullptr || g_test_delegate == nullptr) 212 DCHECK(delegate == nullptr || g_test_delegate == nullptr)
197 << "SetDelegateForTests does not support interleaving. Delegates should " 213 << "SetDelegateForTests does not support interleaving. Delegates should "
198 << "be set and then cleared one at a time."; 214 << "be set and then cleared one at a time.";
199 g_test_delegate = delegate; 215 g_test_delegate = delegate;
200 } 216 }
201 217
202 // static 218 // static
203 void ContentVerifyJob::SetObserverForTests(TestObserver* observer) { 219 void ContentVerifyJob::SetObserverForTests(TestObserver* observer) {
204 g_test_observer = observer; 220 g_test_observer = observer;
205 } 221 }
206 222
207 void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) { 223 void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
208 DCHECK(!failed_); 224 DCHECK(!failed_);
209 failed_ = true; 225 failed_ = true;
210 if (!failure_callback_.is_null()) { 226 if (!failure_callback_.is_null()) {
211 VLOG(1) << "job failed for " << hash_reader_->extension_id() << " " 227 VLOG(1) << "job failed for " << hash_reader_->extension_id() << " "
212 << hash_reader_->relative_path().MaybeAsASCII() 228 << hash_reader_->relative_path().MaybeAsASCII()
213 << " reason:" << reason; 229 << " reason:" << reason;
214 failure_callback_.Run(reason); 230 failure_callback_.Run(reason);
215 failure_callback_.Reset(); 231 failure_callback_.Reset();
216 } 232 }
217 if (g_test_observer) 233 if (g_test_observer) {
218 g_test_observer->JobFinished( 234 g_test_observer->JobFinished(hash_reader_->extension_id(),
219 hash_reader_->extension_id(), hash_reader_->relative_path(), failed_); 235 hash_reader_->relative_path(), reason);
236 }
220 } 237 }
221 238
222 } // namespace extensions 239 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/content_verify_job.h ('k') | extensions/browser/content_verify_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698