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 |