172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file. 472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/safe_browsing/prefix_set.h" 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <algorithm> 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/file_util.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/logging.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/md5.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/rand_util.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "testing/gtest/include/gtest/gtest.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "testing/platform_test.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace { 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass PrefixSetTest : public PlatformTest { 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected: 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Constants for the v1 format. 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kMagicOffset = 0 * sizeof(uint32); 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kVersionOffset = 1 * sizeof(uint32); 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kIndexSizeOffset = 2 * sizeof(uint32); 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kDeltasSizeOffset = 3 * sizeof(uint32); 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const size_t kPayloadOffset = 4 * sizeof(uint32); 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Generate a set of random prefixes to share between tests. For 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // most tests this generation was a large fraction of the test time. 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void SetUpTestCase() { 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < 50000; ++i) { 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SBPrefix prefix = static_cast<SBPrefix>(base::RandUint64()); 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen shared_prefixes_.push_back(prefix); 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Sort for use with PrefixSet constructor. 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(shared_prefixes_.begin(), shared_prefixes_.end()); 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check that all elements of |prefixes| are in |prefix_set|, and 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // that nearby elements are not (for lack of a more sensible set of 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // items to check for absence). 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void CheckPrefixes(safe_browsing::PrefixSet* prefix_set, 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<SBPrefix> &prefixes) { 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The set can generate the prefixes it believes it has, so that's 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // a good starting point. 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::set<SBPrefix> check(prefixes.begin(), prefixes.end()); 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes_copy; 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set->GetPrefixes(&prefixes_copy); 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(prefixes_copy.size(), check.size()); 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(std::equal(check.begin(), check.end(), prefixes_copy.begin())); 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < prefixes.size(); ++i) { 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(prefix_set->Exists(prefixes[i])); 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SBPrefix left_sibling = prefixes[i] - 1; 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (check.count(left_sibling) == 0) 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set->Exists(left_sibling)); 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SBPrefix right_sibling = prefixes[i] + 1; 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (check.count(right_sibling) == 0) 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set->Exists(right_sibling)); 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Generate a |PrefixSet| file from |shared_prefixes_|, store it in 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // a temporary file, and return the filename in |filenamep|. 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Returns |true| on success. 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool GetPrefixSetFile(FilePath* filenamep) { 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!temp_dir_.IsValid() && !temp_dir_.CreateUniqueTempDir()) 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename = temp_dir_.path().AppendASCII("PrefixSetTest"); 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(shared_prefixes_); 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!prefix_set.WriteFile(filename)) 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return false; 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *filenamep = filename; 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return true; 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Helper function to read the int32 value at |offset|, increment it 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // by |inc|, and write it back in place. |fp| should be opened in 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // r+ mode. 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void IncrementIntAt(FILE* fp, long offset, int inc) { 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int32 value = 0; 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NE(-1, fseek(fp, offset, SEEK_SET)); 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(1U, fread(&value, sizeof(value), 1, fp)); 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen value += inc; 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NE(-1, fseek(fp, offset, SEEK_SET)); 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(1U, fwrite(&value, sizeof(value), 1, fp)); 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Helper function to re-generated |fp|'s checksum to be correct for 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the file's contents. |fp| should be opened in r+ mode. 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static void CleanChecksum(FILE* fp) { 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MD5Context context; 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MD5Init(&context); 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NE(-1, fseek(fp, 0, SEEK_END)); 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen long file_size = ftell(fp); 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t payload_size = static_cast<size_t>(file_size) - sizeof(MD5Digest); 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t digested_size = 0; 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NE(-1, fseek(fp, 0, SEEK_SET)); 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen while (digested_size < payload_size) { 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen char buf[1024]; 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t nitems = std::min(payload_size - digested_size, sizeof(buf)); 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(nitems, fread(buf, 1, nitems, fp)); 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MD5Update(&context, &buf, nitems); 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen digested_size += nitems; 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(digested_size, payload_size); 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(static_cast<long>(digested_size), ftell(fp)); 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MD5Digest new_digest; 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MD5Final(&new_digest, &context); 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NE(-1, fseek(fp, digested_size, SEEK_SET)); 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(1U, fwrite(&new_digest, sizeof(new_digest), 1, fp)); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(file_size, ftell(fp)); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Open |filename| and increment the int32 at |offset| by |inc|. 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Then re-generate the checksum to account for the new contents. 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void ModifyAndCleanChecksum(const FilePath& filename, long offset, int inc) { 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int64 size_64; 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(file_util::GetFileSize(filename, &size_64)); 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_util::ScopedFILE file(file_util::OpenFile(filename, "r+b")); 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IncrementIntAt(file.get(), offset, inc); 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CleanChecksum(file.get()); 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int64 new_size_64; 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(file_util::GetFileSize(filename, &new_size_64)); 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(new_size_64, size_64); 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Tests should not modify this shared resource. 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static std::vector<SBPrefix> shared_prefixes_; 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ScopedTempDir temp_dir_; 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::vector<SBPrefix> PrefixSetTest::shared_prefixes_; 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that a small sparse random input works. 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, Baseline) { 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(shared_prefixes_); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CheckPrefixes(&prefix_set, shared_prefixes_); 15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that the empty set doesn't appear to have anything in it. 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, Empty) { 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<SBPrefix> empty; 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(empty); 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 0; i < shared_prefixes_.size(); ++i) { 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set.Exists(shared_prefixes_[i])); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Single-element set should work fine. 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, OneElement) { 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<SBPrefix> prefixes(100, 0); 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(prefixes); 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set.Exists(-1)); 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(prefix_set.Exists(prefixes[0])); 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set.Exists(1)); 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check that |GetPrefixes()| returns the same set of prefixes as 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // was passed in. 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes_copy; 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set.GetPrefixes(&prefixes_copy); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(1U, prefixes_copy.size()); 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(prefixes[0], prefixes_copy[0]); 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Edges of the 32-bit integer range. 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, IntMinMax) { 18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<SBPrefix> prefixes; 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Using bit patterns rather than portable constants because this 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // really is testing how the entire 32-bit integer range is handled. 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x00000000); 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x0000FFFF); 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x7FFF0000); 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x7FFFFFFF); 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x80000000); 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0x8000FFFF); 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0xFFFF0000); 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(0xFFFFFFFF); 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(prefixes.begin(), prefixes.end()); 19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen safe_browsing::PrefixSet prefix_set(prefixes); 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check that |GetPrefixes()| returns the same set of prefixes as 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // was passed in. 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes_copy; 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set.GetPrefixes(&prefixes_copy); 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(prefixes_copy.size(), prefixes.size()); 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes_copy.begin())); 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// A range with only large deltas. 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, AllBig) { 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes; 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SBPrefix kVeryPositive = 1000 * 1000 * 1000; 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SBPrefix kVeryNegative = -kVeryPositive; 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const unsigned kDelta = 10 * 1000 * 1000; 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (SBPrefix prefix = kVeryNegative; 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix < kVeryPositive; prefix += kDelta) { 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.push_back(prefix); 22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::sort(prefixes.begin(), prefixes.end()); 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(prefixes); 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Check that |GetPrefixes()| returns the same set of prefixes as 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // was passed in. 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes_copy; 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set.GetPrefixes(&prefixes_copy); 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(prefixes_copy.size(), prefixes.size()); 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefixes_copy.begin())); 23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use artificial inputs to test various edge cases in Exists(). 23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Items before the lowest item aren't present. Items after the 23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// largest item aren't present. Create a sequence of items with 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// deltas above and below 2^16, and make sure they're all present. 24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Create a very long sequence with deltas below 2^16 to test crossing 24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// |kMaxRun|. 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, EdgeCases) { 24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<SBPrefix> prefixes; 24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const SBPrefix kVeryPositive = 1000 * 1000 * 1000; 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const SBPrefix kVeryNegative = -kVeryPositive; 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Put in a very negative prefix. 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SBPrefix prefix = kVeryNegative; 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Add a sequence with very large deltas. 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen unsigned delta = 100 * 1000 * 1000; 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (int i = 0; i < 10; ++i) { 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefix += delta; 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Add a sequence with deltas that start out smaller than the 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // maximum delta, and end up larger. Also include some duplicates. 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delta = 256 * 256 - 100; 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (int i = 0; i < 200; ++i) { 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefix += delta; 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delta++; 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Add a long sequence with deltas smaller than the maximum delta, 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // so a new index item will be injected. 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delta = 256 * 256 - 1; 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefix = kVeryPositive - delta * 1000; 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (int i = 0; i < 1000; ++i) { 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefix += delta; 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefixes.push_back(prefix); 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen delta--; 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 280dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::sort(prefixes.begin(), prefixes.end()); 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen safe_browsing::PrefixSet prefix_set(prefixes); 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 283dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Check that |GetPrefixes()| returns the same set of prefixes as 284dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // was passed in. 285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::vector<SBPrefix> prefixes_copy; 286dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefix_set.GetPrefixes(&prefixes_copy); 287dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefixes.erase(std::unique(prefixes.begin(), prefixes.end()), prefixes.end()); 288dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_EQ(prefixes_copy.size(), prefixes.size()); 289dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen EXPECT_TRUE(std::equal(prefixes.begin(), prefixes.end(), 290dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen prefixes_copy.begin())); 291dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Items before and after the set are not present, and don't crash. 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_FALSE(prefix_set.Exists(kVeryNegative - 100)); 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_FALSE(prefix_set.Exists(kVeryPositive + 100)); 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Check that the set correctly flags all of the inputs, and also 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // check items just above and below the inputs to make sure they 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // aren't present. 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < prefixes.size(); ++i) { 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_TRUE(prefix_set.Exists(prefixes[i])); 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_FALSE(prefix_set.Exists(prefixes[i] - 1)); 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EXPECT_FALSE(prefix_set.Exists(prefixes[i] + 1)); 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Similar to Baseline test, but write the set out to a file and read 308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// it back in before testing. 309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, ReadWrite) { 310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(prefix_set.get()); 316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CheckPrefixes(prefix_set.get(), shared_prefixes_); 318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Check that |CleanChecksum()| makes an acceptable checksum. 321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionHelpers) { 322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This will modify data in |index_|, which will fail the digest check. 326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_util::ScopedFILE file(file_util::OpenFile(filename, "r+b")); 327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen IncrementIntAt(file.get(), kPayloadOffset, 1); 328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Fix up the checksum and it will read successfully (though the 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // data will be wrong). 335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(file_util::OpenFile(filename, "r+b")); 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen CleanChecksum(file.get()); 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set.reset(safe_browsing::PrefixSet::LoadFile(filename)); 339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(prefix_set.get()); 340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Bad |index_| size is caught by the sanity check. 343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionMagic) { 344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE( 348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ModifyAndCleanChecksum(filename, kMagicOffset, 1)); 349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Bad |index_| size is caught by the sanity check. 355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionVersion) { 356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE( 360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ModifyAndCleanChecksum(filename, kVersionOffset, 1)); 361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Bad |index_| size is caught by the sanity check. 367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionIndexSize) { 368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE( 372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ModifyAndCleanChecksum(filename, kIndexSizeOffset, 1)); 373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Bad |deltas_| size is caught by the sanity check. 379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionDeltasSize) { 380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE( 384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ModifyAndCleanChecksum(filename, kDeltasSizeOffset, 1)); 385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that the digest catches corruption in the middle of the file 391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// (in the payload between the header and the digest). 392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionPayload) { 393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_util::ScopedFILE file(file_util::OpenFile(filename, "r+b")); 397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), 666, 1)); 398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test corruption in the digest itself. 405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionDigest) { 406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int64 size_64; 410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(file_util::GetFileSize(filename, &size_64)); 411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_util::ScopedFILE file(file_util::OpenFile(filename, "r+b")); 412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen long digest_offset = static_cast<long>(size_64 - sizeof(MD5Digest)); 413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_NO_FATAL_FAILURE(IncrementIntAt(file.get(), digest_offset, 1)); 414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test excess data after the digest (fails the size test). 421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, CorruptionExcess) { 422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen FilePath filename; 423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(GetPrefixSetFile(&filename)); 424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Add some junk to the trunk. 426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file_util::ScopedFILE file(file_util::OpenFile(filename, "ab")); 427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const char buf[] = "im in ur base, killing ur d00dz."; 428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_EQ(strlen(buf), fwrite(buf, 1, strlen(buf), file.get())); 429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen file.reset(); 430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen scoped_ptr<safe_browsing::PrefixSet> 431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen prefix_set(safe_browsing::PrefixSet::LoadFile(filename)); 432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_FALSE(prefix_set.get()); 433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(shess): Remove once the problem is debugged. But, until then, 436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// make sure the accessors work! 437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(PrefixSetTest, DebuggingAccessors) { 438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<SBPrefix> prefixes; 439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::unique_copy(shared_prefixes_.begin(), shared_prefixes_.end(), 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::back_inserter(prefixes)); 441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen safe_browsing::PrefixSet prefix_set(prefixes); 442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(prefixes.size(), prefix_set.GetSize()); 444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set.IsDeltaAt(0)); 445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen for (size_t i = 1; i < prefixes.size(); ++i) { 446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const int delta = prefixes[i] - prefixes[i - 1]; 447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (delta > 0xFFFF) { 448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_FALSE(prefix_set.IsDeltaAt(i)); 449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ASSERT_TRUE(prefix_set.IsDeltaAt(i)); 451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen EXPECT_EQ(delta, prefix_set.DeltaAt(i)); 452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} // namespace 457