Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #ifndef COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ | 5 #ifndef COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ |
| 6 #define COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ | 6 #define COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ |
| 7 | 7 |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/sequenced_task_runner.h" | 10 #include "base/sequenced_task_runner.h" |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 | 137 |
| 138 // Failed to decode the Rice-encoded additions/removals field. | 138 // Failed to decode the Rice-encoded additions/removals field. |
| 139 RICE_DECODING_FAILURE = 8, | 139 RICE_DECODING_FAILURE = 8, |
| 140 | 140 |
| 141 // Compression type other than RAW and RICE for additions. | 141 // Compression type other than RAW and RICE for additions. |
| 142 UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE = 9, | 142 UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE = 9, |
| 143 | 143 |
| 144 // Compression type other than RAW and RICE for removals. | 144 // Compression type other than RAW and RICE for removals. |
| 145 UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE = 10, | 145 UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE = 10, |
| 146 | 146 |
| 147 // The state of the store did not match the expected checksum sent by the | |
| 148 // server. | |
| 149 CHECKSUM_MISMATCH_FAILURE = 11, | |
| 150 | |
| 147 // Memory space for histograms is determined by the max. ALWAYS | 151 // Memory space for histograms is determined by the max. ALWAYS |
| 148 // ADD NEW VALUES BEFORE THIS ONE. | 152 // ADD NEW VALUES BEFORE THIS ONE. |
| 149 APPLY_UPDATE_RESULT_MAX | 153 APPLY_UPDATE_RESULT_MAX |
| 150 }; | 154 }; |
| 151 | 155 |
| 152 // Factory for creating V4Store. Tests implement this factory to create fake | 156 // Factory for creating V4Store. Tests implement this factory to create fake |
| 153 // stores for testing. | 157 // stores for testing. |
| 154 class V4StoreFactory { | 158 class V4StoreFactory { |
| 155 public: | 159 public: |
| 156 virtual ~V4StoreFactory() {} | 160 virtual ~V4StoreFactory() {} |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, | 248 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, |
| 245 TestHashPrefixExistsInMapWithSingleSize); | 249 TestHashPrefixExistsInMapWithSingleSize); |
| 246 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, | 250 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, |
| 247 TestHashPrefixExistsInMapWithDifferentSizes); | 251 TestHashPrefixExistsInMapWithDifferentSizes); |
| 248 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, | 252 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, |
| 249 TestHashPrefixDoesNotExistInMapWithDifferentSizes); | 253 TestHashPrefixDoesNotExistInMapWithDifferentSizes); |
| 250 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, | 254 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, |
| 251 TestAdditionsWithRiceEncodingFailsWithInvalidInput); | 255 TestAdditionsWithRiceEncodingFailsWithInvalidInput); |
| 252 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestAdditionsWithRiceEncodingSucceeds); | 256 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestAdditionsWithRiceEncodingSucceeds); |
| 253 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestRemovalsWithRiceEncodingSucceeds); | 257 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestRemovalsWithRiceEncodingSucceeds); |
| 258 FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestMergeUpdatesFailsChecksum); | |
| 254 friend class V4StoreTest; | 259 friend class V4StoreTest; |
| 255 | 260 |
| 256 // If |prefix_size| is within expected range, and |raw_hashes| is not invalid, | 261 // If |prefix_size| is within expected range, and |raw_hashes| is not invalid, |
| 257 // then it sets |raw_hashes| as the value at key |prefix_size| in | 262 // then it sets |raw_hashes| as the value at key |prefix_size| in |
| 258 // |additions_map| | 263 // |additions_map| |
| 259 static ApplyUpdateResult AddUnlumpedHashes(PrefixSize prefix_size, | 264 static ApplyUpdateResult AddUnlumpedHashes(PrefixSize prefix_size, |
| 260 const std::string& raw_hashes, | 265 const std::string& raw_hashes, |
| 261 HashPrefixMap* additions_map); | 266 HashPrefixMap* additions_map); |
| 262 | 267 |
| 263 // Get the next unmerged hash prefix in dictionary order from | 268 // Get the next unmerged hash prefix in dictionary order from |
| 264 // |hash_prefix_map|. |iterator_map| is used to determine which hash prefixes | 269 // |hash_prefix_map|. |iterator_map| is used to determine which hash prefixes |
| 265 // have been merged already. Returns true if there are any unmerged hash | 270 // have been merged already. Returns true if there are any unmerged hash |
| 266 // prefixes in the list. | 271 // prefixes in the list. |
| 267 static bool GetNextSmallestUnmergedPrefix( | 272 static bool GetNextSmallestUnmergedPrefix( |
| 268 const HashPrefixMap& hash_prefix_map, | 273 const HashPrefixMap& hash_prefix_map, |
| 269 const IteratorMap& iterator_map, | 274 const IteratorMap& iterator_map, |
| 270 HashPrefix* smallest_hash_prefix); | 275 HashPrefix* smallest_hash_prefix); |
| 271 | 276 |
| 272 // Returns true if |hash_prefix| exists between |begin| and |end| iterators. | 277 // Returns true if |hash_prefix| exists between |begin| and |end| iterators. |
| 273 static bool HashPrefixMatches(const HashPrefix& hash_prefix, | 278 static bool HashPrefixMatches(const HashPrefix& hash_prefix, |
| 274 const HashPrefixes::const_iterator& begin, | 279 const HashPrefixes::const_iterator& begin, |
| 275 const HashPrefixes::const_iterator& end); | 280 const HashPrefixes::const_iterator& end); |
| 276 | 281 |
| 277 // For each key in |hash_prefix_map|, sets the iterator at that key | 282 // For each key in |hash_prefix_map|, sets the iterator at that key |
| 278 // |iterator_map| to hash_prefix_map[key].begin(). | 283 // |iterator_map| to hash_prefix_map[key].begin(). |
| 279 static void InitializeIteratorMap(const HashPrefixMap& hash_prefix_map, | 284 static void InitializeIteratorMap(const HashPrefixMap& hash_prefix_map, |
| 280 IteratorMap* iterator_map); | 285 IteratorMap* iterator_map); |
| 281 | 286 |
| 287 // Processes the FULL_UPDATE |response| from the server, updates the V4Store | |
| 288 // in |new_store|, and writes the merged store to disk. If processing the | |
| 289 // |response| succeeds, it returns APPLY_UPDATE_SUCCESS. | |
| 290 // This method is only called when we receive a FULL_UPDATE from the server. | |
| 291 static ApplyUpdateResult ProcessFullUpdateAndWriteToDisk( | |
| 292 std::unique_ptr<ListUpdateResponse> response, | |
| 293 const std::unique_ptr<V4Store>& new_store); | |
| 294 | |
| 295 // Processes a FULL_UPDATE |response| and updates |new_store|. If processing | |
| 296 // the |response| succeeds, it returns APPLY_UPDATE_SUCCESS. | |
| 297 // This method is called when we receive a FULL_UPDATE from the server, and | |
| 298 // when we read a store file from disk on startup. | |
| 299 static ApplyUpdateResult ProcessFullUpdate( | |
| 300 const std::unique_ptr<ListUpdateResponse>& response, | |
| 301 V4Store* new_store); | |
|
Nathan Parker
2016/08/08 21:17:19
To consider:
It starts to get a bit murky when yo
vakh (use Gerrit instead)
2016/08/08 22:46:47
Agree. Made them non-static.
| |
| 302 | |
| 303 // Merges the hash prefixes in |hash_prefix_map_old| and |response|, updates | |
| 304 // the |hash_prefix_map_| and |state_| in |new_store|, and writes the merged | |
| 305 // store to disk. If processing succeeds, it returns APPLY_UPDATE_SUCCESS. | |
| 306 // This method is only called when we receive a PARTIAL_UPDATE from the | |
| 307 // server. | |
| 308 static ApplyUpdateResult ProcessPartialUpdateAndWriteToDisk( | |
| 309 const HashPrefixMap& hash_prefix_map_old, | |
| 310 std::unique_ptr<ListUpdateResponse> response, | |
| 311 const std::unique_ptr<V4Store>& new_store); | |
| 312 | |
| 313 // Merges the hash prefixes in |hash_prefix_map_old| and |response|, and | |
| 314 // updates the |hash_prefix_map_| and |state_| in |new_store|. If processing | |
| 315 // succeeds, it returns APPLY_UPDATE_SUCCESS. | |
| 316 static ApplyUpdateResult ProcessUpdate( | |
| 317 const HashPrefixMap& hash_prefix_map_old, | |
| 318 const std::unique_ptr<ListUpdateResponse>& response, | |
| 319 V4Store* new_store); | |
| 320 | |
| 282 // Reserve the appropriate string size so that the string size of the merged | 321 // Reserve the appropriate string size so that the string size of the merged |
| 283 // list is exact. This ignores the space that would otherwise be released by | 322 // list is exact. This ignores the space that would otherwise be released by |
| 284 // deletions specified in the update because it is non-trivial to calculate | 323 // deletions specified in the update because it is non-trivial to calculate |
| 285 // those deletions upfront. This isn't so bad since deletions are supposed to | 324 // those deletions upfront. This isn't so bad since deletions are supposed to |
| 286 // be small and infrequent. | 325 // be small and infrequent. |
| 287 static void ReserveSpaceInPrefixMap(const HashPrefixMap& other_prefixes_map, | 326 static void ReserveSpaceInPrefixMap(const HashPrefixMap& other_prefixes_map, |
| 288 HashPrefixMap* prefix_map_to_update); | 327 HashPrefixMap* prefix_map_to_update); |
| 289 | 328 |
| 290 // Updates the |additions_map| with the additions received in the partial | 329 // Updates the |additions_map| with the additions received in the partial |
| 291 // update from the server. | 330 // update from the server. |
| 292 static ApplyUpdateResult UpdateHashPrefixMapFromAdditions( | 331 static ApplyUpdateResult UpdateHashPrefixMapFromAdditions( |
| 293 const ::google::protobuf::RepeatedPtrField<ThreatEntrySet>& additions, | 332 const ::google::protobuf::RepeatedPtrField<ThreatEntrySet>& additions, |
| 294 HashPrefixMap* additions_map); | 333 HashPrefixMap* additions_map); |
| 295 | 334 |
| 296 // Merges the prefix map from the old store (|old_hash_prefix_map|) and the | 335 // Merges the prefix map from the old store (|old_hash_prefix_map|) and the |
| 297 // update (additions_map) to populate the prefix map for the current store. | 336 // update (additions_map) to populate the prefix map for the current store. |
| 298 // The indices in the |raw_removals| list, which may be NULL, are not merged. | 337 // The indices in the |raw_removals| list, which may be NULL, are not merged. |
| 338 // The SHA256 checksum of the final list of hash prefixes, in lexographically | |
| 339 // sorted order, must match |expected_checksum| (if it's not empty). | |
| 299 ApplyUpdateResult MergeUpdate(const HashPrefixMap& old_hash_prefix_map, | 340 ApplyUpdateResult MergeUpdate(const HashPrefixMap& old_hash_prefix_map, |
| 300 const HashPrefixMap& additions_map, | 341 const HashPrefixMap& additions_map, |
| 301 const ::google::protobuf::RepeatedField< | 342 const ::google::protobuf::RepeatedField< |
| 302 ::google::protobuf::int32>* raw_removals); | 343 ::google::protobuf::int32>* raw_removals, |
| 303 | 344 const std::string& expected_checksum); |
| 304 // Processes the FULL_UPDATE |response| from the server and updates the | |
| 305 // V4Store in |new_store| and writes it to disk. If processing the |response| | |
| 306 // succeeds, it returns APPLY_UPDATE_SUCCESS. | |
| 307 ApplyUpdateResult ProcessFullUpdate( | |
| 308 std::unique_ptr<ListUpdateResponse> response, | |
| 309 const std::unique_ptr<V4Store>& new_store); | |
| 310 | |
| 311 // Processes the PARTIAL_UPDATE |response| from the server and updates the | |
| 312 // V4Store in |new_store|. If processing the |response| succeeds, it returns | |
| 313 // APPLY_UPDATE_SUCCESS. | |
| 314 ApplyUpdateResult ProcessPartialUpdate( | |
| 315 std::unique_ptr<ListUpdateResponse> response, | |
| 316 const std::unique_ptr<V4Store>& new_store); | |
| 317 | 345 |
| 318 // Reads the state of the store from the file on disk and returns the reason | 346 // Reads the state of the store from the file on disk and returns the reason |
| 319 // for the failure or reports success. | 347 // for the failure or reports success. |
| 320 StoreReadResult ReadFromDisk(); | 348 StoreReadResult ReadFromDisk(); |
| 321 | 349 |
| 322 // Writes the FULL_UPDATE |response| to disk as a V4StoreFileFormat proto. | 350 // Writes the FULL_UPDATE |response| to disk as a V4StoreFileFormat proto. |
| 323 StoreWriteResult WriteToDisk( | 351 StoreWriteResult WriteToDisk( |
| 324 std::unique_ptr<ListUpdateResponse> response) const; | 352 std::unique_ptr<ListUpdateResponse> response) const; |
| 325 | 353 |
| 326 // The state of the store as returned by the PVer4 server in the last applied | 354 // The state of the store as returned by the PVer4 server in the last applied |
| 327 // update response. | 355 // update response. |
| 328 std::string state_; | 356 std::string state_; |
| 329 const base::FilePath store_path_; | 357 const base::FilePath store_path_; |
| 330 HashPrefixMap hash_prefix_map_; | 358 HashPrefixMap hash_prefix_map_; |
| 331 const scoped_refptr<base::SequencedTaskRunner> task_runner_; | 359 const scoped_refptr<base::SequencedTaskRunner> task_runner_; |
| 332 }; | 360 }; |
| 333 | 361 |
| 334 std::ostream& operator<<(std::ostream& os, const V4Store& store); | 362 std::ostream& operator<<(std::ostream& os, const V4Store& store); |
| 335 | 363 |
| 336 } // namespace safe_browsing | 364 } // namespace safe_browsing |
| 337 | 365 |
| 338 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ | 366 #endif // COMPONENTS_SAFE_BROWSING_DB_V4_STORE_H_ |
| OLD | NEW |