| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/files/scoped_file.h" | 8 #include "base/files/scoped_file.h" |
| 9 #include "base/md5.h" | 9 #include "base/md5.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 // Helper to find the next shard boundary. | 387 // Helper to find the next shard boundary. |
| 388 template <class T> | 388 template <class T> |
| 389 bool prefix_bounder(SBPrefix val, const T& elt) { | 389 bool prefix_bounder(SBPrefix val, const T& elt) { |
| 390 return val < elt.GetAddPrefix(); | 390 return val < elt.GetAddPrefix(); |
| 391 } | 391 } |
| 392 | 392 |
| 393 // Container for partial database state. Includes add/sub prefixes/hashes, plus | 393 // Container for partial database state. Includes add/sub prefixes/hashes, plus |
| 394 // aggregate operations on same. | 394 // aggregate operations on same. |
| 395 class StateInternal { | 395 class StateInternal { |
| 396 public: | 396 public: |
| 397 explicit StateInternal(const std::vector<SBAddFullHash>& pending_adds) | |
| 398 : add_full_hashes_(pending_adds.begin(), pending_adds.end()) { | |
| 399 } | |
| 400 | |
| 401 StateInternal() {} | 397 StateInternal() {} |
| 402 | 398 |
| 403 // Append indicated amount of data from |fp|. | 399 // Append indicated amount of data from |fp|. |
| 404 bool AppendData(size_t add_prefix_count, size_t sub_prefix_count, | 400 bool AppendData(size_t add_prefix_count, size_t sub_prefix_count, |
| 405 size_t add_hash_count, size_t sub_hash_count, | 401 size_t add_hash_count, size_t sub_hash_count, |
| 406 FILE* fp, base::MD5Context* context) { | 402 FILE* fp, base::MD5Context* context) { |
| 407 return | 403 return |
| 408 ReadToContainer(&add_prefixes_, add_prefix_count, fp, context) && | 404 ReadToContainer(&add_prefixes_, add_prefix_count, fp, context) && |
| 409 ReadToContainer(&sub_prefixes_, sub_prefix_count, fp, context) && | 405 ReadToContainer(&sub_prefixes_, sub_prefix_count, fp, context) && |
| 410 ReadToContainer(&add_full_hashes_, add_hash_count, fp, context) && | 406 ReadToContainer(&add_full_hashes_, add_hash_count, fp, context) && |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 | 725 |
| 730 StateInternal db_state; | 726 StateInternal db_state; |
| 731 if (!ReadDbStateHelper(filename_, &db_state)) | 727 if (!ReadDbStateHelper(filename_, &db_state)) |
| 732 return OnCorruptDatabase(); | 728 return OnCorruptDatabase(); |
| 733 | 729 |
| 734 add_full_hashes->swap(db_state.add_full_hashes_); | 730 add_full_hashes->swap(db_state.add_full_hashes_); |
| 735 return true; | 731 return true; |
| 736 } | 732 } |
| 737 | 733 |
| 738 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id, | 734 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id, |
| 739 base::Time receive_time, | |
| 740 const SBFullHash& full_hash) { | 735 const SBFullHash& full_hash) { |
| 741 add_hashes_.push_back(SBAddFullHash(chunk_id, receive_time, full_hash)); | 736 add_hashes_.push_back(SBAddFullHash(chunk_id, full_hash)); |
| 742 return true; | 737 return true; |
| 743 } | 738 } |
| 744 | 739 |
| 745 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id, | 740 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id, |
| 746 int32 add_chunk_id, | 741 int32 add_chunk_id, |
| 747 SBPrefix prefix) { | 742 SBPrefix prefix) { |
| 748 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix)); | 743 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix)); |
| 749 return true; | 744 return true; |
| 750 } | 745 } |
| 751 | 746 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 !WriteContainer(sub_hashes_, new_file_.get(), NULL)) | 860 !WriteContainer(sub_hashes_, new_file_.get(), NULL)) |
| 866 return false; | 861 return false; |
| 867 | 862 |
| 868 ++chunks_written_; | 863 ++chunks_written_; |
| 869 | 864 |
| 870 // Clear everything to save memory. | 865 // Clear everything to save memory. |
| 871 return ClearChunkBuffers(); | 866 return ClearChunkBuffers(); |
| 872 } | 867 } |
| 873 | 868 |
| 874 bool SafeBrowsingStoreFile::DoUpdate( | 869 bool SafeBrowsingStoreFile::DoUpdate( |
| 875 const std::vector<SBAddFullHash>& pending_adds, | |
| 876 safe_browsing::PrefixSetBuilder* builder, | 870 safe_browsing::PrefixSetBuilder* builder, |
| 877 std::vector<SBAddFullHash>* add_full_hashes_result) { | 871 std::vector<SBAddFullHash>* add_full_hashes_result) { |
| 878 DCHECK(file_.get() || empty_); | 872 DCHECK(file_.get() || empty_); |
| 879 DCHECK(new_file_.get()); | 873 DCHECK(new_file_.get()); |
| 880 CHECK(builder); | 874 CHECK(builder); |
| 881 CHECK(add_full_hashes_result); | 875 CHECK(add_full_hashes_result); |
| 882 | 876 |
| 883 // Rewind the temporary storage. | 877 // Rewind the temporary storage. |
| 884 if (!FileRewind(new_file_.get())) | 878 if (!FileRewind(new_file_.get())) |
| 885 return false; | 879 return false; |
| 886 | 880 |
| 887 // Get chunk file's size for validating counts. | 881 // Get chunk file's size for validating counts. |
| 888 int64 update_size = 0; | 882 int64 update_size = 0; |
| 889 if (!base::GetFileSize(TemporaryFileForFilename(filename_), &update_size)) | 883 if (!base::GetFileSize(TemporaryFileForFilename(filename_), &update_size)) |
| 890 return OnCorruptDatabase(); | 884 return OnCorruptDatabase(); |
| 891 | 885 |
| 892 // Track update size to answer questions at http://crbug.com/72216 . | 886 // Track update size to answer questions at http://crbug.com/72216 . |
| 893 // Log small updates as 1k so that the 0 (underflow) bucket can be | 887 // Log small updates as 1k so that the 0 (underflow) bucket can be |
| 894 // used for "empty" in SafeBrowsingDatabase. | 888 // used for "empty" in SafeBrowsingDatabase. |
| 895 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", | 889 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", |
| 896 std::max(static_cast<int>(update_size / 1024), 1)); | 890 std::max(static_cast<int>(update_size / 1024), 1)); |
| 897 | 891 |
| 898 // Chunk updates to integrate. | 892 // Chunk updates to integrate. |
| 899 StateInternal new_state(pending_adds); | 893 StateInternal new_state; |
| 900 | 894 |
| 901 // Read update chunks. | 895 // Read update chunks. |
| 902 for (int i = 0; i < chunks_written_; ++i) { | 896 for (int i = 0; i < chunks_written_; ++i) { |
| 903 ChunkHeader header; | 897 ChunkHeader header; |
| 904 | 898 |
| 905 int64 ofs = ftell(new_file_.get()); | 899 int64 ofs = ftell(new_file_.get()); |
| 906 if (ofs == -1) | 900 if (ofs == -1) |
| 907 return false; | 901 return false; |
| 908 | 902 |
| 909 if (!ReadItem(&header, new_file_.get(), NULL)) | 903 if (!ReadItem(&header, new_file_.get(), NULL)) |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 return false; | 1123 return false; |
| 1130 | 1124 |
| 1131 // Record counts before swapping to caller. | 1125 // Record counts before swapping to caller. |
| 1132 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count); | 1126 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count); |
| 1133 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count); | 1127 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count); |
| 1134 | 1128 |
| 1135 return true; | 1129 return true; |
| 1136 } | 1130 } |
| 1137 | 1131 |
| 1138 bool SafeBrowsingStoreFile::FinishUpdate( | 1132 bool SafeBrowsingStoreFile::FinishUpdate( |
| 1139 const std::vector<SBAddFullHash>& pending_adds, | |
| 1140 safe_browsing::PrefixSetBuilder* builder, | 1133 safe_browsing::PrefixSetBuilder* builder, |
| 1141 std::vector<SBAddFullHash>* add_full_hashes_result) { | 1134 std::vector<SBAddFullHash>* add_full_hashes_result) { |
| 1142 DCHECK(builder); | 1135 DCHECK(builder); |
| 1143 DCHECK(add_full_hashes_result); | 1136 DCHECK(add_full_hashes_result); |
| 1144 | 1137 |
| 1145 if (!DoUpdate(pending_adds, builder, add_full_hashes_result)) { | 1138 if (!DoUpdate(builder, add_full_hashes_result)) { |
| 1146 CancelUpdate(); | 1139 CancelUpdate(); |
| 1147 return false; | 1140 return false; |
| 1148 } | 1141 } |
| 1149 | 1142 |
| 1150 DCHECK(!new_file_.get()); | 1143 DCHECK(!new_file_.get()); |
| 1151 DCHECK(!file_.get()); | 1144 DCHECK(!file_.get()); |
| 1152 | 1145 |
| 1153 return Close(); | 1146 return Close(); |
| 1154 } | 1147 } |
| 1155 | 1148 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 // With SQLite support gone, one way to get to this code is if the | 1202 // With SQLite support gone, one way to get to this code is if the |
| 1210 // existing file is a SQLite file. Make sure the journal file is | 1203 // existing file is a SQLite file. Make sure the journal file is |
| 1211 // also removed. | 1204 // also removed. |
| 1212 const base::FilePath journal_filename( | 1205 const base::FilePath journal_filename( |
| 1213 basename.value() + FILE_PATH_LITERAL("-journal")); | 1206 basename.value() + FILE_PATH_LITERAL("-journal")); |
| 1214 if (base::PathExists(journal_filename)) | 1207 if (base::PathExists(journal_filename)) |
| 1215 base::DeleteFile(journal_filename, false); | 1208 base::DeleteFile(journal_filename, false); |
| 1216 | 1209 |
| 1217 return true; | 1210 return true; |
| 1218 } | 1211 } |
| OLD | NEW |