Bug 1311935 - P1. Make ActiveTables() work for safebrowsing v4. r=francois
authorDimiL <dlee@mozilla.com>
Fri, 07 Apr 2017 14:30:11 +0800
changeset 560267 905fdf381f58b358c9c89e4e7bdee4822a5e3372
parent 560266 ce2cbd3fc918ab913b42b57c2a2748ceb4f28296
child 560268 7e77f122340b4760bb598891ec87a66e19a7d856
push id53365
push userjichen@mozilla.com
push dateTue, 11 Apr 2017 08:35:12 +0000
reviewersfrancois
bugs1311935
milestone55.0a1
Bug 1311935 - P1. Make ActiveTables() work for safebrowsing v4. r=francois This patch fixes that Classifier::ActiveTables doesn't return v4 tables. Classifier::mActiveTablesCache is generated by scanning safebrowsing directory. We use Classifier::ScanStoreDir to do the work, but it will ignore subdirectory. Since v4 tables are stored in subdirectory 'google4', mActiveTablesCache doesn't include v4 tables. Fix this issue by checking subdirectory recursively in ScanStoreDir. MozReview-Commit-ID: I6pa6e4bFND
toolkit/components/url-classifier/Classifier.cpp
toolkit/components/url-classifier/Classifier.h
--- a/toolkit/components/url-classifier/Classifier.cpp
+++ b/toolkit/components/url-classifier/Classifier.cpp
@@ -388,25 +388,32 @@ Classifier::TableRequest(nsACString& aRe
 
   // Generating v2 table info.
   nsTArray<nsCString> tables;
   ActiveTables(tables);
   for (uint32_t i = 0; i < tables.Length(); i++) {
     HashStore store(tables[i], GetProvider(tables[i]), mRootStoreDirectory);
 
     nsresult rv = store.Open();
-    if (NS_FAILED(rv))
+    if (NS_FAILED(rv)) {
       continue;
+    }
+
+    ChunkSet &adds = store.AddChunks();
+    ChunkSet &subs = store.SubChunks();
+
+    // Open HashStore will always succeed even that is not a v2 table.
+    // So skip tables without add and sub chunks.
+    if (adds.Length() == 0 && subs.Length() == 0) {
+      continue;
+    }
 
     aResult.Append(store.TableName());
     aResult.Append(';');
 
-    ChunkSet &adds = store.AddChunks();
-    ChunkSet &subs = store.SubChunks();
-
     if (adds.Length() > 0) {
       aResult.AppendLiteral("a:");
       nsAutoCString addList;
       adds.Serialize(addList);
       aResult.Append(addList);
     }
 
     if (subs.Length() > 0) {
@@ -917,67 +924,87 @@ Classifier::DropStores()
 }
 
 nsresult
 Classifier::RegenActiveTables()
 {
   mActiveTablesCache.Clear();
 
   nsTArray<nsCString> foundTables;
-  ScanStoreDir(foundTables);
+  ScanStoreDir(mRootStoreDirectory, foundTables);
 
   for (uint32_t i = 0; i < foundTables.Length(); i++) {
     nsCString table(foundTables[i]);
-    HashStore store(table, GetProvider(table), mRootStoreDirectory);
 
-    nsresult rv = store.Open();
-    if (NS_FAILED(rv))
-      continue;
-
-    LookupCache *lookupCache = GetLookupCache(store.TableName());
+    LookupCache *lookupCache = GetLookupCache(table);
     if (!lookupCache) {
       continue;
     }
 
-    if (!lookupCache->IsPrimed())
+    if (!lookupCache->IsPrimed()) {
       continue;
+    }
 
-    const ChunkSet &adds = store.AddChunks();
-    const ChunkSet &subs = store.SubChunks();
+    if (LookupCache::Cast<LookupCacheV4>(lookupCache)) {
+      LOG(("Active v4 table: %s", table.get()));
+    } else {
+      HashStore store(table, GetProvider(table), mRootStoreDirectory);
 
-    if (adds.Length() == 0 && subs.Length() == 0)
-      continue;
+      nsresult rv = store.Open();
+      if (NS_FAILED(rv)) {
+        continue;
+      }
+
+      const ChunkSet &adds = store.AddChunks();
+      const ChunkSet &subs = store.SubChunks();
 
-    LOG(("Active table: %s", store.TableName().get()));
-    mActiveTablesCache.AppendElement(store.TableName());
+      if (adds.Length() == 0 && subs.Length() == 0) {
+        continue;
+      }
+
+      LOG(("Active v2 table: %s", store.TableName().get()));
+    }
+
+    mActiveTablesCache.AppendElement(table);
   }
 
   return NS_OK;
 }
 
 nsresult
-Classifier::ScanStoreDir(nsTArray<nsCString>& aTables)
+Classifier::ScanStoreDir(nsIFile* aDirectory, nsTArray<nsCString>& aTables)
 {
   nsCOMPtr<nsISimpleEnumerator> entries;
-  nsresult rv = mRootStoreDirectory->GetDirectoryEntries(getter_AddRefs(entries));
+  nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool hasMore;
   while (NS_SUCCEEDED(rv = entries->HasMoreElements(&hasMore)) && hasMore) {
     nsCOMPtr<nsISupports> supports;
     rv = entries->GetNext(getter_AddRefs(supports));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
 
+    // If |file| is a directory, recurse to find its entries as well.
+    bool isDirectory;
+    if (NS_FAILED(file->IsDirectory(&isDirectory))) {
+      continue;
+    }
+    if (isDirectory) {
+      ScanStoreDir(file, aTables);
+      continue;
+    }
+
     nsCString leafName;
     rv = file->GetNativeLeafName(leafName);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCString suffix(NS_LITERAL_CSTRING(".sbstore"));
+    // Both v2 and v4 contain .pset file
+    nsCString suffix(NS_LITERAL_CSTRING(".pset"));
 
     int32_t dot = leafName.RFind(suffix, 0);
     if (dot != -1) {
       leafName.Cut(dot, suffix.Length());
       aTables.AppendElement(leafName);
     }
   }
   NS_ENSURE_SUCCESS(rv, rv);
--- a/toolkit/components/url-classifier/Classifier.h
+++ b/toolkit/components/url-classifier/Classifier.h
@@ -147,17 +147,17 @@ private:
   // and on-disk data.
   void RemoveUpdateIntermediaries();
 
 #ifdef MOZ_SAFEBROWSING_DUMP_FAILED_UPDATES
   already_AddRefed<nsIFile> GetFailedUpdateDirectroy();
   nsresult DumpFailedUpdate();
 #endif
 
-  nsresult ScanStoreDir(nsTArray<nsCString>& aTables);
+  nsresult ScanStoreDir(nsIFile* aDirectory, nsTArray<nsCString>& aTables);
 
   nsresult UpdateHashStore(nsTArray<TableUpdate*>* aUpdates,
                            const nsACString& aTable);
 
   nsresult UpdateTableV4(nsTArray<TableUpdate*>* aUpdates,
                          const nsACString& aTable);
 
   nsresult UpdateCache(TableUpdate* aUpdates);