Remove safe-browsing false-positive tracking.
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_store_file_unittest.cc
blobac8002f5d6ef61084cfd036684e49a059382f4b0
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
3 // found in the LICENSE file.
5 #include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
7 #include "base/bind.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/md5.h"
10 #include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "testing/platform_test.h"
14 namespace {
16 class SafeBrowsingStoreFileTest : public PlatformTest {
17 public:
18 virtual void SetUp() {
19 PlatformTest::SetUp();
21 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
23 filename_ = temp_dir_.path();
24 filename_ = filename_.AppendASCII("SafeBrowsingTestStore");
26 store_.reset(new SafeBrowsingStoreFile());
27 store_->Init(filename_,
28 base::Bind(&SafeBrowsingStoreFileTest::OnCorruptionDetected,
29 base::Unretained(this)));
30 corruption_detected_ = false;
32 virtual void TearDown() {
33 if (store_.get())
34 store_->Delete();
35 store_.reset();
37 PlatformTest::TearDown();
40 void OnCorruptionDetected() {
41 corruption_detected_ = true;
44 base::ScopedTempDir temp_dir_;
45 base::FilePath filename_;
46 scoped_ptr<SafeBrowsingStoreFile> store_;
47 bool corruption_detected_;
50 TEST_STORE(SafeBrowsingStoreFileTest, store_.get(), filename_);
52 // Test that Delete() deletes the temporary store, if present.
53 TEST_F(SafeBrowsingStoreFileTest, DeleteTemp) {
54 const base::FilePath temp_file =
55 SafeBrowsingStoreFile::TemporaryFileForFilename(filename_);
57 EXPECT_FALSE(base::PathExists(filename_));
58 EXPECT_FALSE(base::PathExists(temp_file));
60 // Starting a transaction creates a temporary file.
61 EXPECT_TRUE(store_->BeginUpdate());
62 EXPECT_TRUE(base::PathExists(temp_file));
64 // Pull the rug out from under the existing store, simulating a
65 // crash.
66 store_.reset(new SafeBrowsingStoreFile());
67 store_->Init(filename_, base::Closure());
68 EXPECT_FALSE(base::PathExists(filename_));
69 EXPECT_TRUE(base::PathExists(temp_file));
71 // Make sure the temporary file is deleted.
72 EXPECT_TRUE(store_->Delete());
73 EXPECT_FALSE(base::PathExists(filename_));
74 EXPECT_FALSE(base::PathExists(temp_file));
77 // Test basic corruption-handling.
78 TEST_F(SafeBrowsingStoreFileTest, DetectsCorruption) {
79 // Load a store with some data.
80 SafeBrowsingStoreTestStorePrefix(store_.get());
82 // Can successfully open and read the store.
83 std::vector<SBAddFullHash> pending_adds;
84 SBAddPrefixes orig_prefixes;
85 std::vector<SBAddFullHash> orig_hashes;
86 EXPECT_TRUE(store_->BeginUpdate());
87 EXPECT_TRUE(store_->FinishUpdate(pending_adds, &orig_prefixes, &orig_hashes));
88 EXPECT_GT(orig_prefixes.size(), 0U);
89 EXPECT_GT(orig_hashes.size(), 0U);
90 EXPECT_FALSE(corruption_detected_);
92 // Corrupt the store.
93 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
94 const long kOffset = 60;
95 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0);
96 const int32 kZero = 0;
97 int32 previous = kZero;
98 EXPECT_EQ(fread(&previous, sizeof(previous), 1, file.get()), 1U);
99 EXPECT_NE(previous, kZero);
100 EXPECT_EQ(fseek(file.get(), kOffset, SEEK_SET), 0);
101 EXPECT_EQ(fwrite(&kZero, sizeof(kZero), 1, file.get()), 1U);
102 file.reset();
104 // Update fails and corruption callback is called.
105 SBAddPrefixes add_prefixes;
106 std::vector<SBAddFullHash> add_hashes;
107 corruption_detected_ = false;
108 EXPECT_TRUE(store_->BeginUpdate());
109 EXPECT_FALSE(store_->FinishUpdate(pending_adds, &add_prefixes, &add_hashes));
110 EXPECT_TRUE(corruption_detected_);
111 EXPECT_EQ(add_prefixes.size(), 0U);
112 EXPECT_EQ(add_hashes.size(), 0U);
114 // Make it look like there is a lot of add-chunks-seen data.
115 const long kAddChunkCountOffset = 2 * sizeof(int32);
116 const int32 kLargeCount = 1000 * 1000 * 1000;
117 file.reset(file_util::OpenFile(filename_, "rb+"));
118 EXPECT_EQ(fseek(file.get(), kAddChunkCountOffset, SEEK_SET), 0);
119 EXPECT_EQ(fwrite(&kLargeCount, sizeof(kLargeCount), 1, file.get()), 1U);
120 file.reset();
122 // Detects corruption and fails to even begin the update.
123 corruption_detected_ = false;
124 EXPECT_FALSE(store_->BeginUpdate());
125 EXPECT_TRUE(corruption_detected_);
128 TEST_F(SafeBrowsingStoreFileTest, CheckValidity) {
129 // Empty store is valid.
130 EXPECT_FALSE(base::PathExists(filename_));
131 ASSERT_TRUE(store_->BeginUpdate());
132 EXPECT_FALSE(corruption_detected_);
133 EXPECT_TRUE(store_->CheckValidity());
134 EXPECT_FALSE(corruption_detected_);
135 EXPECT_TRUE(store_->CancelUpdate());
137 // A store with some data is valid.
138 EXPECT_FALSE(base::PathExists(filename_));
139 SafeBrowsingStoreTestStorePrefix(store_.get());
140 EXPECT_TRUE(base::PathExists(filename_));
141 ASSERT_TRUE(store_->BeginUpdate());
142 EXPECT_FALSE(corruption_detected_);
143 EXPECT_TRUE(store_->CheckValidity());
144 EXPECT_FALSE(corruption_detected_);
145 EXPECT_TRUE(store_->CancelUpdate());
148 // Corrupt the payload.
149 TEST_F(SafeBrowsingStoreFileTest, CheckValidityPayload) {
150 SafeBrowsingStoreTestStorePrefix(store_.get());
151 EXPECT_TRUE(base::PathExists(filename_));
153 // 37 is the most random prime number. It's also past the header,
154 // as corrupting the header would fail BeginUpdate() in which case
155 // CheckValidity() cannot be called.
156 const size_t kOffset = 37;
159 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
160 EXPECT_EQ(0, fseek(file.get(), kOffset, SEEK_SET));
161 EXPECT_GE(fputs("hello", file.get()), 0);
163 ASSERT_TRUE(store_->BeginUpdate());
164 EXPECT_FALSE(corruption_detected_);
165 EXPECT_FALSE(store_->CheckValidity());
166 EXPECT_TRUE(corruption_detected_);
167 EXPECT_TRUE(store_->CancelUpdate());
170 // Corrupt the checksum.
171 TEST_F(SafeBrowsingStoreFileTest, CheckValidityChecksum) {
172 SafeBrowsingStoreTestStorePrefix(store_.get());
173 EXPECT_TRUE(base::PathExists(filename_));
175 // An offset from the end of the file which is in the checksum.
176 const int kOffset = -static_cast<int>(sizeof(base::MD5Digest));
179 file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb+"));
180 EXPECT_EQ(0, fseek(file.get(), kOffset, SEEK_END));
181 EXPECT_GE(fputs("hello", file.get()), 0);
183 ASSERT_TRUE(store_->BeginUpdate());
184 EXPECT_FALSE(corruption_detected_);
185 EXPECT_FALSE(store_->CheckValidity());
186 EXPECT_TRUE(corruption_detected_);
187 EXPECT_TRUE(store_->CancelUpdate());
190 } // namespace