| 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 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 // Helper to find the next shard boundary. | 435 // Helper to find the next shard boundary. |
| 436 template <class T> | 436 template <class T> |
| 437 bool prefix_bounder(SBPrefix val, const T& elt) { | 437 bool prefix_bounder(SBPrefix val, const T& elt) { |
| 438 return val < elt.GetAddPrefix(); | 438 return val < elt.GetAddPrefix(); |
| 439 } | 439 } |
| 440 | 440 |
| 441 // Container for partial database state. Includes add/sub prefixes/hashes, plus | 441 // Container for partial database state. Includes add/sub prefixes/hashes, plus |
| 442 // aggregate operations on same. | 442 // aggregate operations on same. |
| 443 class StateInternal { | 443 class StateInternal { |
| 444 public: | 444 public: |
| 445 explicit StateInternal(const std::vector<SBAddFullHash>& pending_adds) | |
| 446 : add_full_hashes_(pending_adds.begin(), pending_adds.end()) { | |
| 447 } | |
| 448 | |
| 449 StateInternal() {} | 445 StateInternal() {} |
| 450 | 446 |
| 451 // Append indicated amount of data from |fp|. | 447 // Append indicated amount of data from |fp|. |
| 452 bool AppendData(size_t add_prefix_count, size_t sub_prefix_count, | 448 bool AppendData(size_t add_prefix_count, size_t sub_prefix_count, |
| 453 size_t add_hash_count, size_t sub_hash_count, | 449 size_t add_hash_count, size_t sub_hash_count, |
| 454 FILE* fp, base::MD5Context* context) { | 450 FILE* fp, base::MD5Context* context) { |
| 455 return | 451 return |
| 456 ReadToContainer(&add_prefixes_, add_prefix_count, fp, context) && | 452 ReadToContainer(&add_prefixes_, add_prefix_count, fp, context) && |
| 457 ReadToContainer(&sub_prefixes_, sub_prefix_count, fp, context) && | 453 ReadToContainer(&sub_prefixes_, sub_prefix_count, fp, context) && |
| 458 ReadToContainer(&add_full_hashes_, add_hash_count, fp, context) && | 454 ReadToContainer(&add_full_hashes_, add_hash_count, fp, context) && |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 | 768 |
| 773 StateInternal db_state; | 769 StateInternal db_state; |
| 774 if (!ReadDbStateHelper(filename_, &db_state)) | 770 if (!ReadDbStateHelper(filename_, &db_state)) |
| 775 return OnCorruptDatabase(); | 771 return OnCorruptDatabase(); |
| 776 | 772 |
| 777 add_full_hashes->swap(db_state.add_full_hashes_); | 773 add_full_hashes->swap(db_state.add_full_hashes_); |
| 778 return true; | 774 return true; |
| 779 } | 775 } |
| 780 | 776 |
| 781 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id, | 777 bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id, |
| 782 base::Time receive_time, | |
| 783 const SBFullHash& full_hash) { | 778 const SBFullHash& full_hash) { |
| 784 add_hashes_.push_back(SBAddFullHash(chunk_id, receive_time, full_hash)); | 779 add_hashes_.push_back(SBAddFullHash(chunk_id, full_hash)); |
| 785 return true; | 780 return true; |
| 786 } | 781 } |
| 787 | 782 |
| 788 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id, | 783 bool SafeBrowsingStoreFile::WriteSubPrefix(int32 chunk_id, |
| 789 int32 add_chunk_id, | 784 int32 add_chunk_id, |
| 790 SBPrefix prefix) { | 785 SBPrefix prefix) { |
| 791 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix)); | 786 sub_prefixes_.push_back(SBSubPrefix(chunk_id, add_chunk_id, prefix)); |
| 792 return true; | 787 return true; |
| 793 } | 788 } |
| 794 | 789 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 !WriteContainer(sub_hashes_, new_file_.get(), NULL)) | 903 !WriteContainer(sub_hashes_, new_file_.get(), NULL)) |
| 909 return false; | 904 return false; |
| 910 | 905 |
| 911 ++chunks_written_; | 906 ++chunks_written_; |
| 912 | 907 |
| 913 // Clear everything to save memory. | 908 // Clear everything to save memory. |
| 914 return ClearChunkBuffers(); | 909 return ClearChunkBuffers(); |
| 915 } | 910 } |
| 916 | 911 |
| 917 bool SafeBrowsingStoreFile::DoUpdate( | 912 bool SafeBrowsingStoreFile::DoUpdate( |
| 918 const std::vector<SBAddFullHash>& pending_adds, | |
| 919 safe_browsing::PrefixSetBuilder* builder, | 913 safe_browsing::PrefixSetBuilder* builder, |
| 920 std::vector<SBAddFullHash>* add_full_hashes_result) { | 914 std::vector<SBAddFullHash>* add_full_hashes_result) { |
| 921 DCHECK(file_.get() || empty_); | 915 DCHECK(file_.get() || empty_); |
| 922 DCHECK(new_file_.get()); | 916 DCHECK(new_file_.get()); |
| 923 CHECK(builder); | 917 CHECK(builder); |
| 924 CHECK(add_full_hashes_result); | 918 CHECK(add_full_hashes_result); |
| 925 | 919 |
| 926 // Rewind the temporary storage. | 920 // Rewind the temporary storage. |
| 927 if (!FileRewind(new_file_.get())) | 921 if (!FileRewind(new_file_.get())) |
| 928 return false; | 922 return false; |
| 929 | 923 |
| 930 // Get chunk file's size for validating counts. | 924 // Get chunk file's size for validating counts. |
| 931 int64 update_size = 0; | 925 int64 update_size = 0; |
| 932 if (!base::GetFileSize(TemporaryFileForFilename(filename_), &update_size)) | 926 if (!base::GetFileSize(TemporaryFileForFilename(filename_), &update_size)) |
| 933 return OnCorruptDatabase(); | 927 return OnCorruptDatabase(); |
| 934 | 928 |
| 935 // Track update size to answer questions at http://crbug.com/72216 . | 929 // Track update size to answer questions at http://crbug.com/72216 . |
| 936 // Log small updates as 1k so that the 0 (underflow) bucket can be | 930 // Log small updates as 1k so that the 0 (underflow) bucket can be |
| 937 // used for "empty" in SafeBrowsingDatabase. | 931 // used for "empty" in SafeBrowsingDatabase. |
| 938 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", | 932 UMA_HISTOGRAM_COUNTS("SB2.DatabaseUpdateKilobytes", |
| 939 std::max(static_cast<int>(update_size / 1024), 1)); | 933 std::max(static_cast<int>(update_size / 1024), 1)); |
| 940 | 934 |
| 941 // Chunk updates to integrate. | 935 // Chunk updates to integrate. |
| 942 StateInternal new_state(pending_adds); | 936 StateInternal new_state; |
| 943 | 937 |
| 944 // Read update chunks. | 938 // Read update chunks. |
| 945 for (int i = 0; i < chunks_written_; ++i) { | 939 for (int i = 0; i < chunks_written_; ++i) { |
| 946 ChunkHeader header; | 940 ChunkHeader header; |
| 947 | 941 |
| 948 int64 ofs = ftell(new_file_.get()); | 942 int64 ofs = ftell(new_file_.get()); |
| 949 if (ofs == -1) | 943 if (ofs == -1) |
| 950 return false; | 944 return false; |
| 951 | 945 |
| 952 if (!ReadItem(&header, new_file_.get(), NULL)) | 946 if (!ReadItem(&header, new_file_.get(), NULL)) |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 return false; | 1168 return false; |
| 1175 | 1169 |
| 1176 // Record counts before swapping to caller. | 1170 // Record counts before swapping to caller. |
| 1177 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count); | 1171 UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefix_count); |
| 1178 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count); | 1172 UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefix_count); |
| 1179 | 1173 |
| 1180 return true; | 1174 return true; |
| 1181 } | 1175 } |
| 1182 | 1176 |
| 1183 bool SafeBrowsingStoreFile::FinishUpdate( | 1177 bool SafeBrowsingStoreFile::FinishUpdate( |
| 1184 const std::vector<SBAddFullHash>& pending_adds, | |
| 1185 safe_browsing::PrefixSetBuilder* builder, | 1178 safe_browsing::PrefixSetBuilder* builder, |
| 1186 std::vector<SBAddFullHash>* add_full_hashes_result) { | 1179 std::vector<SBAddFullHash>* add_full_hashes_result) { |
| 1187 DCHECK(builder); | 1180 DCHECK(builder); |
| 1188 DCHECK(add_full_hashes_result); | 1181 DCHECK(add_full_hashes_result); |
| 1189 | 1182 |
| 1190 if (!DoUpdate(pending_adds, builder, add_full_hashes_result)) { | 1183 if (!DoUpdate(builder, add_full_hashes_result)) { |
| 1191 CancelUpdate(); | 1184 CancelUpdate(); |
| 1192 return false; | 1185 return false; |
| 1193 } | 1186 } |
| 1194 | 1187 |
| 1195 DCHECK(!new_file_.get()); | 1188 DCHECK(!new_file_.get()); |
| 1196 DCHECK(!file_.get()); | 1189 DCHECK(!file_.get()); |
| 1197 | 1190 |
| 1198 return Close(); | 1191 return Close(); |
| 1199 } | 1192 } |
| 1200 | 1193 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 // With SQLite support gone, one way to get to this code is if the | 1247 // With SQLite support gone, one way to get to this code is if the |
| 1255 // existing file is a SQLite file. Make sure the journal file is | 1248 // existing file is a SQLite file. Make sure the journal file is |
| 1256 // also removed. | 1249 // also removed. |
| 1257 const base::FilePath journal_filename( | 1250 const base::FilePath journal_filename( |
| 1258 basename.value() + FILE_PATH_LITERAL("-journal")); | 1251 basename.value() + FILE_PATH_LITERAL("-journal")); |
| 1259 if (base::PathExists(journal_filename)) | 1252 if (base::PathExists(journal_filename)) |
| 1260 base::DeleteFile(journal_filename, false); | 1253 base::DeleteFile(journal_filename, false); |
| 1261 | 1254 |
| 1262 return true; | 1255 return true; |
| 1263 } | 1256 } |
| OLD | NEW |