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 #include "base/base64.h" | 5 #include "base/base64.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "components/safe_browsing_db/v4_rice.h" | 12 #include "components/safe_browsing_db/v4_rice.h" |
| 13 #include "components/safe_browsing_db/v4_store.h" | 13 #include "components/safe_browsing_db/v4_store.h" |
| 14 #include "components/safe_browsing_db/v4_store.pb.h" | 14 #include "components/safe_browsing_db/v4_store.pb.h" |
| 15 #include "crypto/sha2.h" | |
| 15 | 16 |
| 16 namespace safe_browsing { | 17 namespace safe_browsing { |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 const uint32_t kFileMagic = 0x600D71FE; | 20 const uint32_t kFileMagic = 0x600D71FE; |
| 20 | 21 |
| 21 const uint32_t kFileVersion = 9; | 22 const uint32_t kFileVersion = 9; |
| 22 | 23 |
| 23 // The minimum expected size (in bytes) of a hash-prefix. | 24 // The minimum expected size (in bytes) of a hash-prefix. |
| 24 const uint32_t kMinHashPrefixLength = 4; | 25 const uint32_t kMinHashPrefixLength = 4; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 return base::StringPrintf("path: %" PRIsFP "; state: %s", | 107 return base::StringPrintf("path: %" PRIsFP "; state: %s", |
| 107 store_path_.value().c_str(), state_base64.c_str()); | 108 store_path_.value().c_str(), state_base64.c_str()); |
| 108 } | 109 } |
| 109 | 110 |
| 110 bool V4Store::Reset() { | 111 bool V4Store::Reset() { |
| 111 // TODO(vakh): Implement skeleton. | 112 // TODO(vakh): Implement skeleton. |
| 112 state_ = ""; | 113 state_ = ""; |
| 113 return true; | 114 return true; |
| 114 } | 115 } |
| 115 | 116 |
| 116 ApplyUpdateResult V4Store::ProcessFullUpdate( | 117 // static |
| 118 ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk( | |
| 119 const HashPrefixMap& hash_prefix_map_old, | |
| 117 std::unique_ptr<ListUpdateResponse> response, | 120 std::unique_ptr<ListUpdateResponse> response, |
| 118 const std::unique_ptr<V4Store>& new_store) { | 121 const std::unique_ptr<V4Store>& new_store) { |
| 119 HashPrefixMap hash_prefix_map; | 122 DCHECK(response->has_response_type()); |
| 120 ApplyUpdateResult apply_update_result = | 123 DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type()); |
| 121 UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); | 124 |
| 122 if (apply_update_result == APPLY_UPDATE_SUCCESS) { | 125 ApplyUpdateResult result = |
| 123 new_store->hash_prefix_map_ = hash_prefix_map; | 126 ProcessUpdate(hash_prefix_map_old, response, new_store.get()); |
|
Nathan Parker
2016/08/08 21:17:19
This change removes the nicely optimized short-cut
vakh (use Gerrit instead)
2016/08/08 22:46:47
Done.
| |
| 127 if (result == APPLY_UPDATE_SUCCESS) { | |
| 128 // TODO(vakh): Create a ListUpdateResponse containing RICE encoded | |
| 129 // hash prefixes and response_type as FULL_UPDATE, and write that to disk. | |
| 130 } | |
| 131 return result; | |
| 132 } | |
| 133 | |
| 134 // static | |
| 135 ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk( | |
| 136 std::unique_ptr<ListUpdateResponse> response, | |
| 137 const std::unique_ptr<V4Store>& new_store) { | |
| 138 ApplyUpdateResult result = ProcessFullUpdate(response, new_store.get()); | |
| 139 if (result == APPLY_UPDATE_SUCCESS) { | |
| 124 RecordStoreWriteResult(new_store->WriteToDisk(std::move(response))); | 140 RecordStoreWriteResult(new_store->WriteToDisk(std::move(response))); |
| 125 } | 141 } |
| 126 return apply_update_result; | 142 return result; |
| 127 } | 143 } |
| 128 | 144 |
| 129 ApplyUpdateResult V4Store::ProcessPartialUpdate( | 145 // static |
| 130 std::unique_ptr<ListUpdateResponse> response, | 146 ApplyUpdateResult V4Store::ProcessFullUpdate( |
| 131 const std::unique_ptr<V4Store>& new_store) { | 147 const std::unique_ptr<ListUpdateResponse>& response, |
| 132 // TODO(vakh): | 148 V4Store* new_store) { |
| 133 // 1. Done: Merge the old store and the new update in new_store. | 149 DCHECK(response->has_response_type()); |
| 134 // 2. Create a ListUpdateResponse containing RICE encoded hash-prefixes and | 150 DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type()); |
| 135 // response_type as FULL_UPDATE, and write that to disk. | 151 return ProcessUpdate(HashPrefixMap(), response, new_store); |
| 136 // 3. Remove this if condition after completing 1. and 2. | 152 } |
| 137 | 153 |
| 154 // static | |
| 155 ApplyUpdateResult V4Store::ProcessUpdate( | |
| 156 const HashPrefixMap& hash_prefix_map_old, | |
| 157 const std::unique_ptr<ListUpdateResponse>& response, | |
| 158 V4Store* new_store) { | |
| 138 const RepeatedField<int32>* raw_removals = nullptr; | 159 const RepeatedField<int32>* raw_removals = nullptr; |
| 139 RepeatedField<int32> rice_removals; | 160 RepeatedField<int32> rice_removals; |
| 140 size_t removals_size = response->removals_size(); | 161 size_t removals_size = response->removals_size(); |
| 141 DCHECK_LE(removals_size, 1u); | 162 DCHECK_LE(removals_size, 1u); |
| 142 if (removals_size == 1) { | 163 if (removals_size == 1) { |
| 143 const ThreatEntrySet& removal = response->removals().Get(0); | 164 const ThreatEntrySet& removal = response->removals().Get(0); |
| 144 const CompressionType compression_type = removal.compression_type(); | 165 const CompressionType compression_type = removal.compression_type(); |
| 145 if (compression_type == RAW) { | 166 if (compression_type == RAW) { |
| 146 raw_removals = &removal.raw_indices().indices(); | 167 raw_removals = &removal.raw_indices().indices(); |
| 147 } else if (compression_type == RICE) { | 168 } else if (compression_type == RICE) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 160 } | 181 } |
| 161 } else { | 182 } else { |
| 162 NOTREACHED() << "Unexpected compression_type type: " << compression_type; | 183 NOTREACHED() << "Unexpected compression_type type: " << compression_type; |
| 163 return UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE; | 184 return UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE; |
| 164 } | 185 } |
| 165 } | 186 } |
| 166 | 187 |
| 167 HashPrefixMap hash_prefix_map; | 188 HashPrefixMap hash_prefix_map; |
| 168 ApplyUpdateResult apply_update_result = | 189 ApplyUpdateResult apply_update_result = |
| 169 UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); | 190 UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); |
| 191 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | |
| 192 return apply_update_result; | |
| 193 } | |
| 170 | 194 |
| 171 if (apply_update_result == APPLY_UPDATE_SUCCESS) { | 195 std::string expected_checksum; |
| 172 apply_update_result = | 196 if (response->has_checksum() && response->checksum().has_sha256()) { |
| 173 new_store->MergeUpdate(hash_prefix_map_, hash_prefix_map, raw_removals); | 197 expected_checksum = response->checksum().sha256(); |
| 174 } | 198 } |
| 175 return apply_update_result; | 199 |
| 200 apply_update_result = new_store->MergeUpdate( | |
| 201 hash_prefix_map_old, hash_prefix_map, raw_removals, expected_checksum); | |
| 202 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | |
| 203 return apply_update_result; | |
| 204 } | |
| 205 | |
| 206 new_store->state_ = response->new_client_state(); | |
| 207 return APPLY_UPDATE_SUCCESS; | |
| 176 } | 208 } |
| 177 | 209 |
| 178 void V4Store::ApplyUpdate( | 210 void V4Store::ApplyUpdate( |
| 179 std::unique_ptr<ListUpdateResponse> response, | 211 std::unique_ptr<ListUpdateResponse> response, |
| 180 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, | 212 const scoped_refptr<base::SingleThreadTaskRunner>& callback_task_runner, |
| 181 UpdatedStoreReadyCallback callback) { | 213 UpdatedStoreReadyCallback callback) { |
| 182 std::unique_ptr<V4Store> new_store( | 214 std::unique_ptr<V4Store> new_store( |
| 183 new V4Store(this->task_runner_, this->store_path_)); | 215 new V4Store(this->task_runner_, this->store_path_)); |
| 184 new_store->state_ = response->new_client_state(); | |
| 185 | 216 |
| 186 ApplyUpdateResult apply_update_result; | 217 ApplyUpdateResult apply_update_result; |
| 187 if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) { | 218 if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) { |
| 188 apply_update_result = ProcessPartialUpdate(std::move(response), new_store); | 219 apply_update_result = ProcessPartialUpdateAndWriteToDisk( |
| 220 hash_prefix_map_, std::move(response), new_store); | |
| 189 } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) { | 221 } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) { |
| 190 apply_update_result = ProcessFullUpdate(std::move(response), new_store); | 222 apply_update_result = |
| 223 ProcessFullUpdateAndWriteToDisk(std::move(response), new_store); | |
| 191 } else { | 224 } else { |
| 192 apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE; | 225 apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE; |
| 193 NOTREACHED() << "Unexpected response type: " << response->response_type(); | 226 NOTREACHED() << "Unexpected response type: " << response->response_type(); |
| 194 } | 227 } |
| 195 | 228 |
| 196 if (apply_update_result == APPLY_UPDATE_SUCCESS) { | 229 if (apply_update_result == APPLY_UPDATE_SUCCESS) { |
| 197 // new_store is done updating, pass it to the callback. | 230 // new_store is done updating, pass it to the callback. |
| 198 callback_task_runner->PostTask( | 231 callback_task_runner->PostTask( |
| 199 FROM_HERE, base::Bind(callback, base::Passed(&new_store))); | 232 FROM_HERE, base::Bind(callback, base::Passed(&new_store))); |
| 200 } else { | 233 } else { |
| 234 DVLOG(1) << "ApplyUpdate failed: " << *this; | |
|
Nathan Parker
2016/08/08 21:17:19
Make it a single DVLOG.
vakh (use Gerrit instead)
2016/08/08 22:46:47
Done.
| |
| 235 DVLOG(1) << "reason: " << apply_update_result; | |
| 201 // new_store failed updating. Pass a nullptr to the callback. | 236 // new_store failed updating. Pass a nullptr to the callback. |
| 202 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr)); | 237 callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr)); |
| 203 } | 238 } |
| 204 | 239 |
| 205 RecordApplyUpdateResult(apply_update_result); | 240 RecordApplyUpdateResult(apply_update_result); |
| 206 } | 241 } |
| 207 | 242 |
| 208 // static | 243 // static |
| 209 ApplyUpdateResult V4Store::UpdateHashPrefixMapFromAdditions( | 244 ApplyUpdateResult V4Store::UpdateHashPrefixMapFromAdditions( |
| 210 const RepeatedPtrField<ThreatEntrySet>& additions, | 245 const RepeatedPtrField<ThreatEntrySet>& additions, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 | 349 |
| 315 const HashPrefixes& existing_prefixes = | 350 const HashPrefixes& existing_prefixes = |
| 316 (*prefix_map_to_update)[prefix_size]; | 351 (*prefix_map_to_update)[prefix_size]; |
| 317 size_t existing_capacity = existing_prefixes.capacity(); | 352 size_t existing_capacity = existing_prefixes.capacity(); |
| 318 | 353 |
| 319 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity + | 354 (*prefix_map_to_update)[prefix_size].reserve(existing_capacity + |
| 320 prefix_length_to_add); | 355 prefix_length_to_add); |
| 321 } | 356 } |
| 322 } | 357 } |
| 323 | 358 |
| 324 ApplyUpdateResult V4Store::MergeUpdate( | 359 ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map, |
| 325 const HashPrefixMap& old_prefixes_map, | 360 const HashPrefixMap& additions_map, |
| 326 const HashPrefixMap& additions_map, | 361 const RepeatedField<int32>* raw_removals, |
| 327 const RepeatedField<int32>* raw_removals) { | 362 const std::string& expected_checksum) { |
| 328 DCHECK(hash_prefix_map_.empty()); | 363 DCHECK(hash_prefix_map_.empty()); |
| 329 hash_prefix_map_.clear(); | 364 hash_prefix_map_.clear(); |
| 330 ReserveSpaceInPrefixMap(old_prefixes_map, &hash_prefix_map_); | 365 ReserveSpaceInPrefixMap(old_prefixes_map, &hash_prefix_map_); |
| 331 ReserveSpaceInPrefixMap(additions_map, &hash_prefix_map_); | 366 ReserveSpaceInPrefixMap(additions_map, &hash_prefix_map_); |
| 332 | 367 |
| 333 IteratorMap old_iterator_map; | 368 IteratorMap old_iterator_map; |
| 334 HashPrefix next_smallest_prefix_old; | 369 HashPrefix next_smallest_prefix_old; |
| 335 InitializeIteratorMap(old_prefixes_map, &old_iterator_map); | 370 InitializeIteratorMap(old_prefixes_map, &old_iterator_map); |
| 336 bool old_has_unmerged = GetNextSmallestUnmergedPrefix( | 371 bool old_has_unmerged = GetNextSmallestUnmergedPrefix( |
| 337 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); | 372 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); |
| 338 | 373 |
| 339 IteratorMap additions_iterator_map; | 374 IteratorMap additions_iterator_map; |
| 340 HashPrefix next_smallest_prefix_additions; | 375 HashPrefix next_smallest_prefix_additions; |
| 341 InitializeIteratorMap(additions_map, &additions_iterator_map); | 376 InitializeIteratorMap(additions_map, &additions_iterator_map); |
| 342 bool additions_has_unmerged = GetNextSmallestUnmergedPrefix( | 377 bool additions_has_unmerged = GetNextSmallestUnmergedPrefix( |
| 343 additions_map, additions_iterator_map, &next_smallest_prefix_additions); | 378 additions_map, additions_iterator_map, &next_smallest_prefix_additions); |
| 344 | 379 |
| 345 // Classical merge sort. | 380 // Classical merge sort. |
| 346 // The two constructs to merge are maps: old_prefixes_map, additions_map. | 381 // The two constructs to merge are maps: old_prefixes_map, additions_map. |
| 347 // At least one of the maps still has elements that need to be merged into the | 382 // At least one of the maps still has elements that need to be merged into the |
| 348 // new store. | 383 // new store. |
| 349 | 384 |
| 385 // |all_prefixes_concatenated| stores the concatenated list of hash prefixes | |
| 386 // in lexographically sorted order. It is used to calculate the |checksum| at | |
| 387 // the end. This checksum is matched against the expected checksum sent by | |
| 388 // the server. | |
| 389 HashPrefixes all_prefixes_concatenated; | |
| 390 bool calculate_checksum = !expected_checksum.empty(); | |
| 391 | |
| 350 // Keep track of the number of elements picked from the old map. This is used | 392 // Keep track of the number of elements picked from the old map. This is used |
| 351 // to determine which elements to drop based on the raw_removals. Note that | 393 // to determine which elements to drop based on the raw_removals. Note that |
| 352 // picked is not the same as merged. A picked element isn't merged if its | 394 // picked is not the same as merged. A picked element isn't merged if its |
| 353 // index is on the raw_removals list. | 395 // index is on the raw_removals list. |
| 354 int total_picked_from_old = 0; | 396 int total_picked_from_old = 0; |
| 355 const int* removals_iter = raw_removals ? raw_removals->begin() : nullptr; | 397 const int* removals_iter = raw_removals ? raw_removals->begin() : nullptr; |
| 356 while (old_has_unmerged || additions_has_unmerged) { | 398 while (old_has_unmerged || additions_has_unmerged) { |
| 357 // If the same hash prefix appears in the existing store and the additions | 399 // If the same hash prefix appears in the existing store and the additions |
| 358 // list, something is clearly wrong. Discard the update. | 400 // list, something is clearly wrong. Discard the update. |
| 359 if (old_has_unmerged && additions_has_unmerged && | 401 if (old_has_unmerged && additions_has_unmerged && |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 373 next_smallest_prefix_size = next_smallest_prefix_old.size(); | 415 next_smallest_prefix_size = next_smallest_prefix_old.size(); |
| 374 | 416 |
| 375 // Update the iterator map, which means that we have merged one hash | 417 // Update the iterator map, which means that we have merged one hash |
| 376 // prefix of size |next_size_for_old| from the old store. | 418 // prefix of size |next_size_for_old| from the old store. |
| 377 old_iterator_map[next_smallest_prefix_size] += next_smallest_prefix_size; | 419 old_iterator_map[next_smallest_prefix_size] += next_smallest_prefix_size; |
| 378 | 420 |
| 379 if (!raw_removals || removals_iter == raw_removals->end() || | 421 if (!raw_removals || removals_iter == raw_removals->end() || |
| 380 *removals_iter != total_picked_from_old) { | 422 *removals_iter != total_picked_from_old) { |
| 381 // Append the smallest hash to the appropriate list. | 423 // Append the smallest hash to the appropriate list. |
| 382 hash_prefix_map_[next_smallest_prefix_size] += next_smallest_prefix_old; | 424 hash_prefix_map_[next_smallest_prefix_size] += next_smallest_prefix_old; |
| 425 | |
| 426 if (calculate_checksum) { | |
| 427 all_prefixes_concatenated += next_smallest_prefix_old; | |
|
Nathan Parker
2016/08/08 21:17:19
Rather than building up another whole copy of the
vakh (use Gerrit instead)
2016/08/08 22:46:47
Done.
| |
| 428 } | |
| 383 } else { | 429 } else { |
| 384 // Element not added to new map. Move the removals iterator forward. | 430 // Element not added to new map. Move the removals iterator forward. |
| 385 removals_iter++; | 431 removals_iter++; |
| 386 } | 432 } |
| 387 | 433 |
| 388 total_picked_from_old++; | 434 total_picked_from_old++; |
| 389 | 435 |
| 390 // Find the next smallest unmerged element in the old store's map. | 436 // Find the next smallest unmerged element in the old store's map. |
| 391 old_has_unmerged = GetNextSmallestUnmergedPrefix( | 437 old_has_unmerged = GetNextSmallestUnmergedPrefix( |
| 392 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); | 438 old_prefixes_map, old_iterator_map, &next_smallest_prefix_old); |
| 393 } else { | 439 } else { |
| 394 next_smallest_prefix_size = next_smallest_prefix_additions.size(); | 440 next_smallest_prefix_size = next_smallest_prefix_additions.size(); |
| 395 | 441 |
| 396 // Append the smallest hash to the appropriate list. | 442 // Append the smallest hash to the appropriate list. |
| 397 hash_prefix_map_[next_smallest_prefix_size] += | 443 hash_prefix_map_[next_smallest_prefix_size] += |
| 398 next_smallest_prefix_additions; | 444 next_smallest_prefix_additions; |
| 399 | 445 |
| 446 if (calculate_checksum) { | |
| 447 all_prefixes_concatenated += next_smallest_prefix_additions; | |
| 448 } | |
| 449 | |
| 400 // Update the iterator map, which means that we have merged one hash | 450 // Update the iterator map, which means that we have merged one hash |
| 401 // prefix of size |next_smallest_prefix_size| from the update. | 451 // prefix of size |next_smallest_prefix_size| from the update. |
| 402 additions_iterator_map[next_smallest_prefix_size] += | 452 additions_iterator_map[next_smallest_prefix_size] += |
| 403 next_smallest_prefix_size; | 453 next_smallest_prefix_size; |
| 404 | 454 |
| 405 // Find the next smallest unmerged element in the additions map. | 455 // Find the next smallest unmerged element in the additions map. |
| 406 additions_has_unmerged = | 456 additions_has_unmerged = |
| 407 GetNextSmallestUnmergedPrefix(additions_map, additions_iterator_map, | 457 GetNextSmallestUnmergedPrefix(additions_map, additions_iterator_map, |
| 408 &next_smallest_prefix_additions); | 458 &next_smallest_prefix_additions); |
| 409 } | 459 } |
| 410 } | 460 } |
| 411 | 461 |
| 462 if (calculate_checksum) { | |
| 463 std::string checksum = crypto::SHA256HashString(all_prefixes_concatenated); | |
| 464 if (checksum != expected_checksum) { | |
| 465 std::string checksum_base64, expected_checksum_base64; | |
| 466 base::Base64Encode(checksum, &checksum_base64); | |
| 467 base::Base64Encode(expected_checksum, &expected_checksum_base64); | |
| 468 DVLOG(1) << "calculated checksum: " << checksum_base64; | |
|
Nathan Parker
2016/08/08 21:17:19
How about making it a single DVLOG, with an error
vakh (use Gerrit instead)
2016/08/08 22:46:47
Done.
| |
| 469 DVLOG(1) << "expected checksum: " << expected_checksum_base64; | |
| 470 return CHECKSUM_MISMATCH_FAILURE; | |
| 471 } | |
| 472 } | |
| 473 | |
| 412 return (!raw_removals || removals_iter == raw_removals->end()) | 474 return (!raw_removals || removals_iter == raw_removals->end()) |
|
Nathan Parker
2016/08/08 21:17:19
It might be useful to check (!raw_removals || remo
vakh (use Gerrit instead)
2016/08/08 22:46:47
Done.
| |
| 413 ? APPLY_UPDATE_SUCCESS | 475 ? APPLY_UPDATE_SUCCESS |
| 414 : REMOVALS_INDEX_TOO_LARGE_FAILURE; | 476 : REMOVALS_INDEX_TOO_LARGE_FAILURE; |
| 415 } | 477 } |
| 416 | 478 |
| 417 StoreReadResult V4Store::ReadFromDisk() { | 479 StoreReadResult V4Store::ReadFromDisk() { |
| 418 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 480 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
| 419 | 481 |
| 420 std::string contents; | 482 std::string contents; |
| 421 bool read_success = base::ReadFileToString(store_path_, &contents); | 483 bool read_success = base::ReadFileToString(store_path_, &contents); |
| 422 if (!read_success) { | 484 if (!read_success) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 443 if (file_format.version_number() != kFileVersion) { | 505 if (file_format.version_number() != kFileVersion) { |
| 444 DVLOG(1) << "File version incompatible: " << file_format.version_number() | 506 DVLOG(1) << "File version incompatible: " << file_format.version_number() |
| 445 << "; expected: " << kFileVersion; | 507 << "; expected: " << kFileVersion; |
| 446 return FILE_VERSION_INCOMPATIBLE_FAILURE; | 508 return FILE_VERSION_INCOMPATIBLE_FAILURE; |
| 447 } | 509 } |
| 448 | 510 |
| 449 if (!file_format.has_list_update_response()) { | 511 if (!file_format.has_list_update_response()) { |
| 450 return HASH_PREFIX_INFO_MISSING_FAILURE; | 512 return HASH_PREFIX_INFO_MISSING_FAILURE; |
| 451 } | 513 } |
| 452 | 514 |
| 453 const ListUpdateResponse& response = file_format.list_update_response(); | 515 std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse); |
| 454 ApplyUpdateResult apply_update_result = UpdateHashPrefixMapFromAdditions( | 516 response->Swap(file_format.mutable_list_update_response()); |
| 455 response.additions(), &hash_prefix_map_); | 517 ApplyUpdateResult apply_update_result = ProcessFullUpdate(response, this); |
| 456 RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); | 518 RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); |
| 457 if (apply_update_result != APPLY_UPDATE_SUCCESS) { | 519 if (apply_update_result != APPLY_UPDATE_SUCCESS) { |
| 458 hash_prefix_map_.clear(); | 520 hash_prefix_map_.clear(); |
| 459 return HASH_PREFIX_MAP_GENERATION_FAILURE; | 521 return HASH_PREFIX_MAP_GENERATION_FAILURE; |
| 460 } | 522 } |
| 461 | 523 |
| 462 state_ = response.new_client_state(); | |
| 463 return READ_SUCCESS; | 524 return READ_SUCCESS; |
| 464 } | 525 } |
| 465 | 526 |
| 466 StoreWriteResult V4Store::WriteToDisk( | 527 StoreWriteResult V4Store::WriteToDisk( |
| 467 std::unique_ptr<ListUpdateResponse> response) const { | 528 std::unique_ptr<ListUpdateResponse> response) const { |
| 468 // Do not write partial updates to the disk. | 529 // Do not write partial updates to the disk. |
| 469 // After merging the updates, the ListUpdateResponse passed to this method | 530 // After merging the updates, the ListUpdateResponse passed to this method |
| 470 // should be a FULL_UPDATE. | 531 // should be a FULL_UPDATE. |
| 471 if (!response->has_response_type() || | 532 if (!response->has_response_type() || |
| 472 response->response_type() != ListUpdateResponse::FULL_UPDATE) { | 533 response->response_type() != ListUpdateResponse::FULL_UPDATE) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 if (result == 0) { | 593 if (result == 0) { |
| 533 return true; | 594 return true; |
| 534 } else if (result < 0) { | 595 } else if (result < 0) { |
| 535 return HashPrefixMatches(hash_prefix, begin, mid); | 596 return HashPrefixMatches(hash_prefix, begin, mid); |
| 536 } else { | 597 } else { |
| 537 return HashPrefixMatches(hash_prefix, mid + prefix_size, end); | 598 return HashPrefixMatches(hash_prefix, mid + prefix_size, end); |
| 538 } | 599 } |
| 539 } | 600 } |
| 540 | 601 |
| 541 } // namespace safe_browsing | 602 } // namespace safe_browsing |
| OLD | NEW |