| 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 if (bytes_left < sizeof(base::MD5Digest)) |
| 267 return OnCorruptDatabase(); |
| 268 bytes_left -= sizeof(base::MD5Digest); |
| 269 |
| 270 // Fold the contents of the file into the checksum. |
| 271 while (bytes_left > 0) { |
| 272 char buf[4096]; |
| 273 const size_t c = std::min(sizeof(buf), bytes_left); |
| 274 const size_t ret = fread(buf, 1, c, file_.get()); |
| 275 |
| 276 // The file's size changed while reading, give up. |
| 277 if (ret != c) |
| 278 return OnCorruptDatabase(); |
| 279 base::MD5Update(&context, base::StringPiece(buf, c)); |
| 280 bytes_left -= c; |
| 281 } |
| 282 |
| 283 // Calculate the digest to this point. |
| 284 base::MD5Digest calculated_digest; |
| 285 base::MD5Final(&calculated_digest, &context); |
| 286 |
| 287 // Read the stored digest and verify it. |
| 288 base::MD5Digest file_digest; |
| 289 if (!ReadItem(&file_digest, file_.get(), NULL)) |
| 290 return OnCorruptDatabase(); |
| 291 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) { |
| 292 RecordFormatEvent(FORMAT_EVENT_VALIDITY_CHECKSUM_FAILURE); |
| 293 return OnCorruptDatabase(); |
| 294 } |
| 295 |
| 296 return true; |
| 297 } |
| 298 |
| 246 void SafeBrowsingStoreFile::Init( | 299 void SafeBrowsingStoreFile::Init( |
| 247 const FilePath& filename, | 300 const FilePath& filename, |
| 248 const base::Closure& corruption_callback | 301 const base::Closure& corruption_callback |
| 249 ) { | 302 ) { |
| 250 filename_ = filename; | 303 filename_ = filename; |
| 251 corruption_callback_ = corruption_callback; | 304 corruption_callback_ = corruption_callback; |
| 252 } | 305 } |
| 253 | 306 |
| 254 bool SafeBrowsingStoreFile::BeginChunk() { | 307 bool SafeBrowsingStoreFile::BeginChunk() { |
| 255 return ClearChunkBuffers(); | 308 return ClearChunkBuffers(); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 | 549 |
| 497 // Calculate the digest to this point. | 550 // Calculate the digest to this point. |
| 498 base::MD5Digest calculated_digest; | 551 base::MD5Digest calculated_digest; |
| 499 base::MD5Final(&calculated_digest, &context); | 552 base::MD5Final(&calculated_digest, &context); |
| 500 | 553 |
| 501 // Read the stored checksum and verify it. | 554 // Read the stored checksum and verify it. |
| 502 base::MD5Digest file_digest; | 555 base::MD5Digest file_digest; |
| 503 if (!ReadItem(&file_digest, file_.get(), NULL)) | 556 if (!ReadItem(&file_digest, file_.get(), NULL)) |
| 504 return OnCorruptDatabase(); | 557 return OnCorruptDatabase(); |
| 505 | 558 |
| 506 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) | 559 if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest))) { |
| 560 RecordFormatEvent(FORMAT_EVENT_UPDATE_CHECKSUM_FAILURE); |
| 507 return OnCorruptDatabase(); | 561 return OnCorruptDatabase(); |
| 562 } |
| 508 | 563 |
| 509 // Close the file so we can later rename over it. | 564 // Close the file so we can later rename over it. |
| 510 file_.reset(); | 565 file_.reset(); |
| 511 } | 566 } |
| 512 DCHECK(!file_.get()); | 567 DCHECK(!file_.get()); |
| 513 | 568 |
| 514 // Rewind the temporary storage. | 569 // Rewind the temporary storage. |
| 515 if (!FileRewind(new_file_.get())) | 570 if (!FileRewind(new_file_.get())) |
| 516 return false; | 571 return false; |
| 517 | 572 |
| (...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()); | 749 out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end()); |
| 695 } | 750 } |
| 696 | 751 |
| 697 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { | 752 void SafeBrowsingStoreFile::DeleteAddChunk(int32 chunk_id) { |
| 698 add_del_cache_.insert(chunk_id); | 753 add_del_cache_.insert(chunk_id); |
| 699 } | 754 } |
| 700 | 755 |
| 701 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { | 756 void SafeBrowsingStoreFile::DeleteSubChunk(int32 chunk_id) { |
| 702 sub_del_cache_.insert(chunk_id); | 757 sub_del_cache_.insert(chunk_id); |
| 703 } | 758 } |
| OLD | NEW |