OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/safe_browsing/safe_browsing_store_file.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h" |
6 | 6 |
7 #include "base/md5.h" | 7 #include "base/md5.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 | 9 |
10 namespace { | 10 namespace { |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 // existing file is a SQLite file. Make sure the journal file is | 236 // existing file is a SQLite file. Make sure the journal file is |
237 // also removed. | 237 // also removed. |
238 const FilePath journal_filename( | 238 const FilePath journal_filename( |
239 filename_.value() + FILE_PATH_LITERAL("-journal")); | 239 filename_.value() + FILE_PATH_LITERAL("-journal")); |
240 if (file_util::PathExists(journal_filename)) | 240 if (file_util::PathExists(journal_filename)) |
241 file_util::Delete(journal_filename, false); | 241 file_util::Delete(journal_filename, false); |
242 | 242 |
243 return true; | 243 return true; |
244 } | 244 } |
245 | 245 |
246 bool SafeBrowsingStoreFile::CheckValidity() { | |
247 if (empty_) | |
248 return true; | |
249 | |
250 // If the file was not empty, it should be open. | |
251 DCHECK(file_.get()); | |
252 | |
253 if (!FileRewind(file_.get())) | |
254 return OnCorruptDatabase(); | |
255 | |
256 int64 size = 0; | |
257 if (!file_util::GetFileSize(filename_, &size)) | |
258 return OnCorruptDatabase(); | |
259 | |
260 base::MD5Context context; | |
261 base::MD5Init(&context); | |
262 | |
263 // Read everything except the final digest. | |
264 size_t bytes_left = static_cast<size_t>(size); | |
265 CHECK(size == static_cast<int64>(bytes_left)); | |
266 bytes_left -= sizeof(base::MD5Digest); | |
mattm
2012/04/23 23:47:48
if the file size is < sizeof(base::MD5Digest) this
Scott Hess - ex-Googler
2012/04/24 01:37:21
Whoa, totally valid, thanks for catching that!
| |
267 | |
268 // Fold the contents of the file into the checksum. | |
269 while (bytes_left > 0) { | |
270 char buf[4096]; | |
271 const size_t c = std::min(sizeof(buf), bytes_left); | |
272 const size_t ret = fread(buf, 1, c, file_.get()); | |
273 | |
274 // The file's size changed while reading, give up. | |
275 if (ret != c) | |
276 return OnCorruptDatabase(); | |
277 base::MD5Update(&context, base::StringPiece(buf, c)); | |
278 bytes_left -= c; | |
279 } | |
280 | |
281 // Calculate the digest to this point. | |
282 base::MD5Digest calculated_digest; | |
283 base::MD5Final(&calculated_digest, &context); | |
284 | |
285 // Read the stored digest and verify it. | |
286 base::MD5Digest file_digest; | |
287 if (!ReadItem(&file_digest, file_.get(), NULL)) | |
Scott Hess - ex-Googler
2012/04/23 22:29:28
|calculated_digest| was from |file|, while |file_d
| |
288 return OnCorruptDatabase(); | |
289 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) { | |
290 RecordFormatEvent(FORMAT_EVENT_VALIDITY_CHECKSUM_FAILURE); | |
291 return OnCorruptDatabase(); | |
292 } | |
293 | |
294 return true; | |
295 } | |
296 | |
246 void SafeBrowsingStoreFile::Init( | 297 void SafeBrowsingStoreFile::Init( |
247 const FilePath& filename, | 298 const FilePath& filename, |
248 const base::Closure& corruption_callback | 299 const base::Closure& corruption_callback |
249 ) { | 300 ) { |
250 filename_ = filename; | 301 filename_ = filename; |
251 corruption_callback_ = corruption_callback; | 302 corruption_callback_ = corruption_callback; |
252 } | 303 } |
253 | 304 |
254 bool SafeBrowsingStoreFile::BeginChunk() { | 305 bool SafeBrowsingStoreFile::BeginChunk() { |
255 return ClearChunkBuffers(); | 306 return ClearChunkBuffers(); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
496 | 547 |
497 // Calculate the digest to this point. | 548 // Calculate the digest to this point. |
498 base::MD5Digest calculated_digest; | 549 base::MD5Digest calculated_digest; |
499 base::MD5Final(&calculated_digest, &context); | 550 base::MD5Final(&calculated_digest, &context); |
500 | 551 |
501 // Read the stored checksum and verify it. | 552 // Read the stored checksum and verify it. |
502 base::MD5Digest file_digest; | 553 base::MD5Digest file_digest; |
503 if (!ReadItem(&file_digest, file_.get(), NULL)) | 554 if (!ReadItem(&file_digest, file_.get(), NULL)) |
504 return OnCorruptDatabase(); | 555 return OnCorruptDatabase(); |
505 | 556 |
506 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) | 557 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) { |
558 RecordFormatEvent(FORMAT_EVENT_UPDATE_CHECKSUM_FAILURE); | |
507 return OnCorruptDatabase(); | 559 return OnCorruptDatabase(); |
560 } | |
508 | 561 |
509 // Close the file so we can later rename over it. | 562 // Close the file so we can later rename over it. |
510 file_.reset(); | 563 file_.reset(); |
511 } | 564 } |
512 DCHECK(!file_.get()); | 565 DCHECK(!file_.get()); |
513 | 566 |
514 // Rewind the temporary storage. | 567 // Rewind the temporary storage. |
515 if (!FileRewind(new_file_.get())) | 568 if (!FileRewind(new_file_.get())) |
516 return false; | 569 return false; |
517 | 570 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end()); | 747 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end()); |
695 } | 748 } |
696 | 749 |
697 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { | 750 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { |
698 add_del_cache_.insert(chunk_id); | 751 add_del_cache_.insert(chunk_id); |
699 } | 752 } |
700 | 753 |
701 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { | 754 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { |
702 sub_del_cache_.insert(chunk_id); | 755 sub_del_cache_.insert(chunk_id); |
703 } | 756 } |
OLD | NEW |