/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Classifier.h" #include "LookupCacheV4.h" #include "nsAppDirectoryServiceDefs.h" #include "Common.h" #define GTEST_SAFEBROWSING_DIR "safebrowsing"_ns static void TestHasPrefix(const nsCString& aURL, bool aExpectedHas, bool aExpectedComplete) { _PrefixArray array = {CreatePrefixFromURL("bravo.com/", 32), CreatePrefixFromURL("browsing.com/", 8), CreatePrefixFromURL("gound.com/", 5), CreatePrefixFromURL("small.com/", 4)}; nsCOMPtr file; NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(file)); file->AppendNative(GTEST_SAFEBROWSING_DIR); RunTestInNewThread([&]() -> void { RefPtr cache = SetupLookupCache(array, file); Completion lookupHash; lookupHash.FromPlaintext(aURL); bool has, confirmed; uint32_t matchLength; // Freshness is not used in V4 so we just put dummy values here. TableFreshnessMap dummy; nsresult rv = cache->Has(lookupHash, &has, &matchLength, &confirmed); EXPECT_EQ(rv, NS_OK); EXPECT_EQ(has, aExpectedHas); EXPECT_EQ(matchLength == COMPLETE_SIZE, aExpectedComplete); EXPECT_EQ(confirmed, false); cache->ClearAll(); }); } TEST(UrlClassifierLookupCacheV4, HasComplete) { TestHasPrefix("bravo.com/"_ns, true, true); } TEST(UrlClassifierLookupCacheV4, HasPrefix) { TestHasPrefix("browsing.com/"_ns, true, false); } TEST(UrlClassifierLookupCacheV4, Nomatch) { TestHasPrefix("nomatch.com/"_ns, false, false); } // Test an existing .pset should be removed after .vlpset is written TEST(UrlClassifierLookupCacheV4, RemoveOldPset) { nsCOMPtr oldPsetFile; NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(oldPsetFile)); oldPsetFile->AppendNative("safebrowsing"_ns); oldPsetFile->AppendNative(GTEST_TABLE_V4 + ".pset"_ns); nsCOMPtr newPsetFile; NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(newPsetFile)); newPsetFile->AppendNative("safebrowsing"_ns); newPsetFile->AppendNative(GTEST_TABLE_V4 + ".vlpset"_ns); // Create the legacy .pset file nsresult rv = oldPsetFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666); EXPECT_EQ(rv, NS_OK); bool exists; rv = oldPsetFile->Exists(&exists); EXPECT_EQ(rv, NS_OK); EXPECT_EQ(exists, true); // Setup the data in lookup cache and write its data to disk RefPtr classifier = GetClassifier(); _PrefixArray array = {CreatePrefixFromURL("entry.com/", 4)}; rv = BuildLookupCache(classifier, GTEST_TABLE_V4, array); EXPECT_EQ(rv, NS_OK); RefPtr cache = classifier->GetLookupCache(GTEST_TABLE_V4, false); rv = cache->WriteFile(); EXPECT_EQ(rv, NS_OK); // .vlpset should exist while .pset should be removed rv = newPsetFile->Exists(&exists); EXPECT_EQ(rv, NS_OK); EXPECT_EQ(exists, true); rv = oldPsetFile->Exists(&exists); EXPECT_EQ(rv, NS_OK); EXPECT_EQ(exists, false); newPsetFile->Remove(false); } // Test the legacy load TEST(UrlClassifierLookupCacheV4, LoadOldPset) { nsCOMPtr oldPsetFile; _PrefixArray array = {CreatePrefixFromURL("entry.com/", 4)}; PrefixStringMap map; PrefixArrayToPrefixStringMap(array, map); // Prepare .pset file on disk { NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(oldPsetFile)); oldPsetFile->AppendNative("safebrowsing"_ns); oldPsetFile->AppendNative(GTEST_TABLE_V4 + ".pset"_ns); RefPtr pset = new VariableLengthPrefixSet; pset->SetPrefixes(map); nsCOMPtr stream; nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), oldPsetFile); EXPECT_EQ(rv, NS_OK); rv = pset->WritePrefixes(stream); EXPECT_EQ(rv, NS_OK); } // Load data from disk RefPtr classifier = GetClassifier(); RefPtr cache = classifier->GetLookupCache(GTEST_TABLE_V4, false); RefPtr cacheV4 = LookupCache::Cast(cache); CheckContent(cacheV4, array); oldPsetFile->Remove(false); } TEST(UrlClassifierLookupCacheV4, BuildAPI) { _PrefixArray init = {_Prefix("alph")}; RefPtr cache = SetupLookupCache(init); _PrefixArray update = {_Prefix("beta")}; PrefixStringMap map; PrefixArrayToPrefixStringMap(update, map); cache->Build(map); EXPECT_TRUE(map.IsEmpty()); CheckContent(cache, update); }