| 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 |