| 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_database.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> | 8 #include <iterator> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 return a.full_hash.prefix < b.full_hash.prefix; | 229 return a.full_hash.prefix < b.full_hash.prefix; |
| 230 } | 230 } |
| 231 | 231 |
| 232 // As compared to the bloom filter, PrefixSet should have these | 232 // As compared to the bloom filter, PrefixSet should have these |
| 233 // properties: | 233 // properties: |
| 234 // - Any bloom filter miss should be a prefix set miss. | 234 // - Any bloom filter miss should be a prefix set miss. |
| 235 // - Any prefix set hit should be a bloom filter hit. | 235 // - Any prefix set hit should be a bloom filter hit. |
| 236 // - Bloom filter false positives are prefix set misses. | 236 // - Bloom filter false positives are prefix set misses. |
| 237 // The following is to log actual performance to verify this. | 237 // The following is to log actual performance to verify this. |
| 238 enum PrefixSetEvent { | 238 enum PrefixSetEvent { |
| 239 PREFIX_SET_EVENT_HIT, | 239 // Hits to prefix set and bloom filter. |
| 240 PREFIX_SET_EVENT_BLOOM_HIT, | 240 PREFIX_SET_HIT, |
| 241 PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT, | 241 PREFIX_SET_BLOOM_HIT, |
| 242 PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT_INVALID, | 242 // These were to track bloom misses which hit the prefix set, with |
| 243 // _INVALID to track where the item didn't appear to actually be in |
| 244 // the prefix set. _INVALID was never hit. |
| 245 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT, |
| 246 PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT_INVALID_OBSOLETE, |
| 247 // GetPrefixes() after creation failed to get the same prefixes. |
| 243 PREFIX_SET_GETPREFIXES_BROKEN, | 248 PREFIX_SET_GETPREFIXES_BROKEN, |
| 244 PREFIX_SET_GETPREFIXES_BROKEN_SIZE, | 249 // Fine-grained tests which didn't provide any good direction. |
| 245 PREFIX_SET_GETPREFIXES_FIRST_BROKEN, | 250 PREFIX_SET_GETPREFIXES_BROKEN_SIZE_OBSOLETE, |
| 246 PREFIX_SET_SBPREFIX_WAS_BROKEN, | 251 PREFIX_SET_GETPREFIXES_FIRST_BROKEN_OBSOLETE, |
| 247 PREFIX_SET_GETPREFIXES_BROKEN_SORTING, | 252 PREFIX_SET_SBPREFIX_WAS_BROKEN_OBSOLETE, |
| 248 PREFIX_SET_GETPREFIXES_BROKEN_DUPLICATION, | 253 PREFIX_SET_GETPREFIXES_BROKEN_SORTING_OBSOLETE, |
| 249 PREFIX_SET_GETPREFIX_UNSORTED_IS_DELTA, | 254 PREFIX_SET_GETPREFIXES_BROKEN_DUPLICATION_OBSOLETE, |
| 250 PREFIX_SET_GETPREFIX_UNSORTED_IS_INDEX, | 255 PREFIX_SET_GETPREFIXES_UNSORTED_IS_DELTA_OBSOLETE, |
| 251 PREFIX_SET_GETPREFIX_CHECKSUM_MISMATCH, | 256 PREFIX_SET_GETPREFIXES_UNSORTED_IS_INDEX_OBSOLETE, |
| 257 // Failed checksum when creating prefix set. |
| 258 PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM, |
| 252 | 259 |
| 253 // Memory space for histograms is determined by the max. ALWAYS ADD | 260 // Memory space for histograms is determined by the max. ALWAYS ADD |
| 254 // NEW VALUES BEFORE THIS ONE. | 261 // NEW VALUES BEFORE THIS ONE. |
| 255 PREFIX_SET_EVENT_MAX | 262 PREFIX_SET_EVENT_MAX |
| 256 }; | 263 }; |
| 257 | 264 |
| 258 void RecordPrefixSetInfo(PrefixSetEvent event_type) { | 265 void RecordPrefixSetInfo(PrefixSetEvent event_type) { |
| 259 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, | 266 UMA_HISTOGRAM_ENUMERATION("SB2.PrefixSetEvent", event_type, |
| 260 PREFIX_SET_EVENT_MAX); | 267 PREFIX_SET_EVENT_MAX); |
| 261 } | 268 } |
| 262 | 269 |
| 270 // Helper to reduce code duplication. |
| 271 safe_browsing::PrefixSet* CreateEmptyPrefixSet() { |
| 272 return new safe_browsing::PrefixSet(std::vector<SBPrefix>()); |
| 273 } |
| 274 |
| 263 // Generate a |PrefixSet| instance from the contents of | 275 // Generate a |PrefixSet| instance from the contents of |
| 264 // |add_prefixes|. Additionally performs various checks to make sure | 276 // |add_prefixes|. Additionally performs various checks to make sure |
| 265 // that the resulting prefix set is valid, so that the | 277 // that the resulting prefix set is valid, so that histograms in |
| 266 // PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT_INVALID histogram in | |
| 267 // ContainsBrowseUrl() can be trustworthy. | 278 // ContainsBrowseUrl() can be trustworthy. |
| 268 safe_browsing::PrefixSet* PrefixSetFromAddPrefixes( | 279 safe_browsing::PrefixSet* PrefixSetFromAddPrefixes( |
| 269 const SBAddPrefixes& add_prefixes) { | 280 const SBAddPrefixes& add_prefixes) { |
| 270 // TODO(shess): If |add_prefixes| were sorted by the prefix, it | 281 // TODO(shess): If |add_prefixes| were sorted by the prefix, it |
| 271 // could be passed directly to |PrefixSet()|, removing the need for | 282 // could be passed directly to |PrefixSet()|, removing the need for |
| 272 // |prefixes|. For now, |prefixes| is useful while debugging | 283 // |prefixes|. For now, |prefixes| is useful while debugging |
| 273 // things. | 284 // things. |
| 274 std::vector<SBPrefix> prefixes; | 285 std::vector<SBPrefix> prefixes; |
| 275 prefixes.reserve(add_prefixes.size()); | 286 prefixes.reserve(add_prefixes.size()); |
| 276 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin(); | 287 for (SBAddPrefixes::const_iterator iter = add_prefixes.begin(); |
| 277 iter != add_prefixes.end(); ++iter) { | 288 iter != add_prefixes.end(); ++iter) { |
| 278 prefixes.push_back(iter->prefix); | 289 prefixes.push_back(iter->prefix); |
| 279 } | 290 } |
| 280 | 291 |
| 281 std::sort(prefixes.begin(), prefixes.end()); | 292 std::sort(prefixes.begin(), prefixes.end()); |
| 282 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), | 293 prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), |
| 283 prefixes.end()); | 294 prefixes.end()); |
| 284 | 295 |
| 285 scoped_ptr<safe_browsing::PrefixSet> | 296 scoped_ptr<safe_browsing::PrefixSet> |
| 286 prefix_set(new safe_browsing::PrefixSet(prefixes)); | 297 prefix_set(new safe_browsing::PrefixSet(prefixes)); |
| 287 | 298 |
| 288 std::vector<SBPrefix> restored; | 299 std::vector<SBPrefix> restored; |
| 289 prefix_set->GetPrefixes(&restored); | 300 prefix_set->GetPrefixes(&restored); |
| 290 | 301 |
| 291 // Expect them to be equal. | 302 // Expect them to be equal. |
| 292 if (restored.size() == prefixes.size() && | 303 if (restored.size() == prefixes.size() && |
| 293 std::equal(prefixes.begin(), prefixes.end(), restored.begin())) | 304 std::equal(prefixes.begin(), prefixes.end(), restored.begin())) |
| 294 return prefix_set.release(); | 305 return prefix_set.release(); |
| 295 | 306 |
| 296 // Log BROKEN for continuity with previous release, and SIZE to | 307 // NOTE(shess): Past histograms have indicated that in a given day, |
| 297 // distinguish which test failed. | 308 // about 1 in 100,000 updates result in a PrefixSet which was |
| 309 // inconsistent relative to the BloomFilter. Windows is about 5x |
| 310 // more likely to build an inconsistent PrefixSet than Mac. A |
| 311 // number of developers have reviewed the code, and I ran extensive |
| 312 // fuzzing with random data, so at this point I'm trying to |
| 313 // demonstrate memory corruption. |
| 314 // |
| 315 // Other findings from past instrumentation: |
| 316 // - half of one percent of brokenness cases implied duplicate items |
| 317 // in |prefixes|. Per the code above, this should not be |
| 318 // possible. |
| 319 // - about 1/20 of broken cases happened more than once for a given |
| 320 // user. Note that empty updates generally don't hit this code at |
| 321 // all, so that may not imply a specific input pattern breaking things. |
| 322 // - about 1/3 of broken cases show a checksum mismatch between the |
| 323 // checksum calculated while creating |prefix_set| and the |
| 324 // checksum calculated immediately after creation. This is almost |
| 325 // certainly memory corruption. |
| 298 NOTREACHED(); | 326 NOTREACHED(); |
| 299 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN); | 327 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN); |
| 300 if (restored.size() != prefixes.size()) | |
| 301 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN_SIZE); | |
| 302 | 328 |
| 303 // Try to distinguish between updates from one broken user and a | 329 // Broken because internal memory was corrupted during construction. |
| 304 // distributed problem. | 330 if (!prefix_set->CheckChecksum()) |
| 305 static bool logged_broken = false; | 331 RecordPrefixSetInfo(PREFIX_SET_CREATE_PREFIX_SET_CHECKSUM); |
| 306 if (!logged_broken) { | |
| 307 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_FIRST_BROKEN); | |
| 308 logged_broken = true; | |
| 309 } | |
| 310 | 332 |
| 311 // This seems so very very unlikely. But if it ever were true, then | 333 // TODO(shess): Test whether |prefixes| changed during construction. |
| 312 // it could explain why GetPrefixes() seemed broken. | |
| 313 if (sizeof(int) != sizeof(int32)) | |
| 314 RecordPrefixSetInfo(PREFIX_SET_SBPREFIX_WAS_BROKEN); | |
| 315 | 334 |
| 316 // Check if memory was corrupted during construction. | 335 return CreateEmptyPrefixSet(); |
| 317 if (!prefix_set->CheckChecksum()) | |
| 318 RecordPrefixSetInfo(PREFIX_SET_GETPREFIX_CHECKSUM_MISMATCH); | |
| 319 | |
| 320 // Check whether |restored| is unsorted, or has duplication. | |
| 321 if (restored.size()) { | |
| 322 size_t unsorted_count = 0; | |
| 323 bool duplicates = false; | |
| 324 SBPrefix prev = restored[0]; | |
| 325 for (size_t i = 0; i < restored.size(); prev = restored[i], ++i) { | |
| 326 if (prev > restored[i]) { | |
| 327 unsorted_count++; | |
| 328 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetUnsortedDifference", | |
| 329 prev - restored[i]); | |
| 330 | |
| 331 // When unsorted, how big is the set, and how far are we into | |
| 332 // it. If the set is very small or large, that might inform | |
| 333 // pursuit of a degenerate case. If the percentage is close | |
| 334 // to 0%, 100%, or 50%, then there might be an interesting | |
| 335 // degenerate case to explore. | |
| 336 UMA_HISTOGRAM_COUNTS("SB2.PrefixSetUnsortedSize", restored.size()); | |
| 337 UMA_HISTOGRAM_PERCENTAGE("SB2.PrefixSetUnsortedPercent", | |
| 338 i * 100 / restored.size()); | |
| 339 | |
| 340 if (prefix_set->IsDeltaAt(i)) { | |
| 341 RecordPrefixSetInfo(PREFIX_SET_GETPREFIX_UNSORTED_IS_DELTA); | |
| 342 | |
| 343 // Histograms require memory on the order of the number of | |
| 344 // buckets, making high-precision logging expensive. For | |
| 345 // now aim for a sense of the range of the problem. | |
| 346 UMA_HISTOGRAM_CUSTOM_COUNTS("SB2.PrefixSetUnsortedDelta", | |
| 347 prefix_set->DeltaAt(i), 1, 0xFFFF, 50); | |
| 348 } else { | |
| 349 RecordPrefixSetInfo(PREFIX_SET_GETPREFIX_UNSORTED_IS_INDEX); | |
| 350 } | |
| 351 } | |
| 352 if (prev == restored[i]) | |
| 353 duplicates = true; | |
| 354 } | |
| 355 | |
| 356 // Record findings. | |
| 357 if (unsorted_count) { | |
| 358 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN_SORTING); | |
| 359 UMA_HISTOGRAM_COUNTS_100("SB2.PrefixSetUnsorted", unsorted_count); | |
| 360 } | |
| 361 if (duplicates) | |
| 362 RecordPrefixSetInfo(PREFIX_SET_GETPREFIXES_BROKEN_DUPLICATION); | |
| 363 | |
| 364 // Fix the problems noted. If |restored| was unsorted, then | |
| 365 // |duplicates| may give a false negative. | |
| 366 if (unsorted_count) | |
| 367 std::sort(restored.begin(), restored.end()); | |
| 368 if (unsorted_count || duplicates) | |
| 369 restored.erase(std::unique(restored.begin(), restored.end()), | |
| 370 restored.end()); | |
| 371 } | |
| 372 | |
| 373 // NOTE(shess): The following could be done using a single | |
| 374 // uber-loop, but it's complicated by needing multiple parallel | |
| 375 // iterators. Didn't seem worthwhile for something that will only | |
| 376 // live for a short period and only fires for one in a million | |
| 377 // updates. | |
| 378 | |
| 379 // Find elements in |restored| which are not in |prefixes|. | |
| 380 std::vector<SBPrefix> difference; | |
| 381 std::set_difference(restored.begin(), restored.end(), | |
| 382 prefixes.begin(), prefixes.end(), | |
| 383 std::back_inserter(difference)); | |
| 384 if (difference.size()) | |
| 385 UMA_HISTOGRAM_COUNTS_100("SB2.PrefixSetRestoredExcess", difference.size()); | |
| 386 | |
| 387 // Find elements in |prefixes| which are not in |restored|. | |
| 388 difference.clear(); | |
| 389 std::set_difference(prefixes.begin(), prefixes.end(), | |
| 390 restored.begin(), restored.end(), | |
| 391 std::back_inserter(difference)); | |
| 392 if (difference.size()) | |
| 393 UMA_HISTOGRAM_COUNTS_100("SB2.PrefixSetRestoredShortfall", | |
| 394 difference.size()); | |
| 395 | |
| 396 return prefix_set.release(); | |
| 397 } | 336 } |
| 398 | 337 |
| 399 } // namespace | 338 } // namespace |
| 400 | 339 |
| 401 // The default SafeBrowsingDatabaseFactory. | 340 // The default SafeBrowsingDatabaseFactory. |
| 402 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { | 341 class SafeBrowsingDatabaseFactoryImpl : public SafeBrowsingDatabaseFactory { |
| 403 public: | 342 public: |
| 404 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( | 343 virtual SafeBrowsingDatabase* CreateSafeBrowsingDatabase( |
| 405 bool enable_download_protection, | 344 bool enable_download_protection, |
| 406 bool enable_client_side_whitelist, | 345 bool enable_client_side_whitelist, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 { | 548 { |
| 610 base::AutoLock locked(lookup_lock_); | 549 base::AutoLock locked(lookup_lock_); |
| 611 full_browse_hashes_.clear(); | 550 full_browse_hashes_.clear(); |
| 612 pending_browse_hashes_.clear(); | 551 pending_browse_hashes_.clear(); |
| 613 prefix_miss_cache_.clear(); | 552 prefix_miss_cache_.clear(); |
| 614 // TODO(shess): This could probably be |bloom_filter_.reset()|. | 553 // TODO(shess): This could probably be |bloom_filter_.reset()|. |
| 615 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * | 554 browse_bloom_filter_ = new BloomFilter(BloomFilter::kBloomFilterMinSize * |
| 616 BloomFilter::kBloomFilterSizeRatio); | 555 BloomFilter::kBloomFilterSizeRatio); |
| 617 // TODO(shess): It is simpler for the code to assume that presence | 556 // TODO(shess): It is simpler for the code to assume that presence |
| 618 // of a bloom filter always implies presence of a prefix set. | 557 // of a bloom filter always implies presence of a prefix set. |
| 619 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>())); | 558 prefix_set_.reset(CreateEmptyPrefixSet()); |
| 620 } | 559 } |
| 621 // Wants to acquire the lock itself. | 560 // Wants to acquire the lock itself. |
| 622 WhitelistEverything(&csd_whitelist_); | 561 WhitelistEverything(&csd_whitelist_); |
| 623 WhitelistEverything(&download_whitelist_); | 562 WhitelistEverything(&download_whitelist_); |
| 624 | 563 |
| 625 return true; | 564 return true; |
| 626 } | 565 } |
| 627 | 566 |
| 628 // TODO(lzheng): Remove matching_list, it is not used anywhere. | 567 // TODO(lzheng): Remove matching_list, it is not used anywhere. |
| 629 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( | 568 bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( |
| (...skipping 17 matching lines...) Expand all Loading... |
| 647 base::AutoLock locked(lookup_lock_); | 586 base::AutoLock locked(lookup_lock_); |
| 648 | 587 |
| 649 if (!browse_bloom_filter_.get()) | 588 if (!browse_bloom_filter_.get()) |
| 650 return false; | 589 return false; |
| 651 DCHECK(prefix_set_.get()); | 590 DCHECK(prefix_set_.get()); |
| 652 | 591 |
| 653 // |prefix_set_| is empty until the first update, only log info if | 592 // |prefix_set_| is empty until the first update, only log info if |
| 654 // not empty. | 593 // not empty. |
| 655 const bool prefix_set_empty = !prefix_set_->GetSize(); | 594 const bool prefix_set_empty = !prefix_set_->GetSize(); |
| 656 | 595 |
| 657 // Used to double-check in case of a hit mis-match. | |
| 658 std::vector<SBPrefix> restored; | |
| 659 | |
| 660 size_t miss_count = 0; | 596 size_t miss_count = 0; |
| 661 for (size_t i = 0; i < full_hashes.size(); ++i) { | 597 for (size_t i = 0; i < full_hashes.size(); ++i) { |
| 662 bool found = prefix_set_->Exists(full_hashes[i].prefix); | 598 bool found = prefix_set_->Exists(full_hashes[i].prefix); |
| 663 | 599 |
| 664 if (browse_bloom_filter_->Exists(full_hashes[i].prefix)) { | 600 if (browse_bloom_filter_->Exists(full_hashes[i].prefix)) { |
| 665 if (!prefix_set_empty) { | 601 if (!prefix_set_empty) { |
| 666 RecordPrefixSetInfo(PREFIX_SET_EVENT_BLOOM_HIT); | 602 RecordPrefixSetInfo(PREFIX_SET_BLOOM_HIT); |
| 603 // This should be less than PREFIX_SET_BLOOM_HIT by the |
| 604 // false positive rate. |
| 667 if (found) | 605 if (found) |
| 668 RecordPrefixSetInfo(PREFIX_SET_EVENT_HIT); | 606 RecordPrefixSetInfo(PREFIX_SET_HIT); |
| 669 } | 607 } |
| 670 prefix_hits->push_back(full_hashes[i].prefix); | 608 prefix_hits->push_back(full_hashes[i].prefix); |
| 671 if (prefix_miss_cache_.count(full_hashes[i].prefix) > 0) | 609 if (prefix_miss_cache_.count(full_hashes[i].prefix) > 0) |
| 672 ++miss_count; | 610 ++miss_count; |
| 673 } else { | 611 } else { |
| 674 // Bloom filter misses should never be in prefix set. Re-create | 612 // Bloom filter misses should never be in prefix set. |
| 675 // the original prefixes and manually search for it, to check if | |
| 676 // there's a bug with how |Exists()| is implemented. | |
| 677 // |UpdateBrowseStore()| previously verified that | |
| 678 // |GetPrefixes()| returns the same prefixes as were passed to | |
| 679 // the constructor. | |
| 680 DCHECK(!found); | 613 DCHECK(!found); |
| 681 if (found && !prefix_set_empty) { | 614 if (found) |
| 682 if (restored.empty()) | 615 RecordPrefixSetInfo(PREFIX_SET_BLOOM_MISS_PREFIX_SET_HIT); |
| 683 prefix_set_->GetPrefixes(&restored); | |
| 684 | |
| 685 // If the item is not in the re-created list, then there is an | |
| 686 // error in |PrefixSet::Exists()|. If the item is in the | |
| 687 // re-created list, then the bloom filter was wrong. | |
| 688 if (std::binary_search(restored.begin(), restored.end(), | |
| 689 full_hashes[i].prefix)) { | |
| 690 RecordPrefixSetInfo(PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT); | |
| 691 } else { | |
| 692 RecordPrefixSetInfo(PREFIX_SET_EVENT_BLOOM_MISS_PREFIX_HIT_INVALID); | |
| 693 } | |
| 694 } | |
| 695 } | 616 } |
| 696 } | 617 } |
| 697 | 618 |
| 698 // If all the prefixes are cached as 'misses', don't issue a GetHash. | 619 // If all the prefixes are cached as 'misses', don't issue a GetHash. |
| 699 if (miss_count == prefix_hits->size()) | 620 if (miss_count == prefix_hits->size()) |
| 700 return false; | 621 return false; |
| 701 | 622 |
| 702 // Find the matching full-hash results. |full_browse_hashes_| are from the | 623 // Find the matching full-hash results. |full_browse_hashes_| are from the |
| 703 // database, |pending_browse_hashes_| are from GetHash requests between | 624 // database, |pending_browse_hashes_| are from GetHash requests between |
| 704 // updates. | 625 // updates. |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1379 | 1300 |
| 1380 const base::TimeTicks before = base::TimeTicks::Now(); | 1301 const base::TimeTicks before = base::TimeTicks::Now(); |
| 1381 browse_bloom_filter_ = BloomFilter::LoadFile(bloom_filter_filename_); | 1302 browse_bloom_filter_ = BloomFilter::LoadFile(bloom_filter_filename_); |
| 1382 DVLOG(1) << "SafeBrowsingDatabaseNew read bloom filter in " | 1303 DVLOG(1) << "SafeBrowsingDatabaseNew read bloom filter in " |
| 1383 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; | 1304 << (base::TimeTicks::Now() - before).InMilliseconds() << " ms"; |
| 1384 | 1305 |
| 1385 if (!browse_bloom_filter_.get()) | 1306 if (!browse_bloom_filter_.get()) |
| 1386 RecordFailure(FAILURE_DATABASE_FILTER_READ); | 1307 RecordFailure(FAILURE_DATABASE_FILTER_READ); |
| 1387 | 1308 |
| 1388 // Use an empty prefix set until the first update. | 1309 // Use an empty prefix set until the first update. |
| 1389 prefix_set_.reset(new safe_browsing::PrefixSet(std::vector<SBPrefix>())); | 1310 prefix_set_.reset(CreateEmptyPrefixSet()); |
| 1390 } | 1311 } |
| 1391 | 1312 |
| 1392 bool SafeBrowsingDatabaseNew::Delete() { | 1313 bool SafeBrowsingDatabaseNew::Delete() { |
| 1393 DCHECK_EQ(creation_loop_, MessageLoop::current()); | 1314 DCHECK_EQ(creation_loop_, MessageLoop::current()); |
| 1394 | 1315 |
| 1395 const bool r1 = browse_store_->Delete(); | 1316 const bool r1 = browse_store_->Delete(); |
| 1396 if (!r1) | 1317 if (!r1) |
| 1397 RecordFailure(FAILURE_DATABASE_STORE_DELETE); | 1318 RecordFailure(FAILURE_DATABASE_STORE_DELETE); |
| 1398 | 1319 |
| 1399 const bool r2 = download_store_.get() ? download_store_->Delete() : true; | 1320 const bool r2 = download_store_.get() ? download_store_->Delete() : true; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1464 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), | 1385 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), |
| 1465 kill_switch)) { | 1386 kill_switch)) { |
| 1466 // The kill switch is whitelisted hence we whitelist all URLs. | 1387 // The kill switch is whitelisted hence we whitelist all URLs. |
| 1467 WhitelistEverything(whitelist); | 1388 WhitelistEverything(whitelist); |
| 1468 } else { | 1389 } else { |
| 1469 base::AutoLock locked(lookup_lock_); | 1390 base::AutoLock locked(lookup_lock_); |
| 1470 whitelist->second = false; | 1391 whitelist->second = false; |
| 1471 whitelist->first.swap(new_whitelist); | 1392 whitelist->first.swap(new_whitelist); |
| 1472 } | 1393 } |
| 1473 } | 1394 } |
| OLD | NEW |