summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-09 05:42:33 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-09 05:42:33 +0000
commit5388e2d3221ad13455602b2afb5e6961245c9c85 (patch)
tree5fc759da9276502057ae278111b29c899ca0d8c6 /chrome
parenta6e9077e9b31c10b339aef3b81a2b550a3e33d23 (diff)
downloadchromium_src-5388e2d3221ad13455602b2afb5e6961245c9c85.zip
chromium_src-5388e2d3221ad13455602b2afb5e6961245c9c85.tar.gz
chromium_src-5388e2d3221ad13455602b2afb5e6961245c9c85.tar.bz2
Remove SQLite safe-browsing backing store.
In October 2010, 7.0 rolled to stable with the safe-browsing database configured to read-from-sqlite and write-to-new-file-format. There is still a long tail of SQLite-format databases in the wild, but very small (and possibly due to a systemic issue with updating, so it may not get smaller). This change flips the switch to no longer support reading the SQLite files. Those users will do a full re-sync with the safe-browsing servers. BUG=58552 TEST=none Review URL: http://codereview.chromium.org/6413022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74253 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_database.cc12
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_database_unittest.cc130
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.h4
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_file.cc103
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_file.h20
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc166
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_sqlite.cc749
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_sqlite.h159
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_sqlite_unittest.cc53
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
11 files changed, 25 insertions, 1374 deletions
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc
index 16e4c55..1e645ce 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc
@@ -13,8 +13,6 @@
#include "base/sha2.h"
#include "chrome/browser/safe_browsing/bloom_filter.h"
#include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
-#include "chrome/browser/safe_browsing/safe_browsing_util.h"
#include "googleurl/src/gurl.h"
namespace {
@@ -206,11 +204,9 @@ SafeBrowsingDatabaseFactory* SafeBrowsingDatabase::factory_ = NULL;
// Factory method, non-thread safe. Caller has to make sure this s called
// on SafeBrowsing Thread.
-// TODO(shess): Milestone-7 is converting from SQLite-based
-// SafeBrowsingDatabaseBloom to the new file format with
-// SafeBrowsingDatabaseNew. Once that conversion is too far along to
-// consider reversing, circle back and lift SafeBrowsingDatabaseNew up
-// to SafeBrowsingDatabase and get rid of the abstract class.
+// TODO(shess): There's no need for a factory any longer. Convert
+// SafeBrowsingDatabaseNew to SafeBrowsingDatabase, and have Create()
+// callers just construct things directly.
SafeBrowsingDatabase* SafeBrowsingDatabase::Create(
bool enable_download_protection) {
if (!factory_)
@@ -259,7 +255,7 @@ void SafeBrowsingDatabase::RecordFailure(FailureType failure_type) {
SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
: creation_loop_(MessageLoop::current()),
- browse_store_(new SafeBrowsingStoreSqlite),
+ browse_store_(new SafeBrowsingStoreFile),
download_store_(NULL),
ALLOW_THIS_IN_INITIALIZER_LIST(reset_factory_(this)) {
DCHECK(browse_store_.get());
diff --git a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
index 8b0cb76..8491212 100644
--- a/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_database_unittest.cc
@@ -14,7 +14,6 @@
#include "base/time.h"
#include "chrome/browser/safe_browsing/safe_browsing_database.h"
#include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
#include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -218,57 +217,6 @@ class ScopedLogMessageIgnorer {
}
};
-// Helper function which corrupts the root page of the indicated
-// table. After this the table can be opened successfully, and
-// queries to other tables work, and possibly queries to this table
-// which only hit an index may work, but queries which hit the table
-// itself should not. Returns |true| on success.
-bool CorruptSqliteTable(const FilePath& filename,
- const std::string& table_name) {
- size_t root_page; // Root page of the table.
- size_t page_size; // Page size of the database.
-
- sql::Connection db;
- if (!db.Open(filename))
- return false;
-
- sql::Statement stmt(db.GetUniqueStatement("PRAGMA page_size"));
- if (!stmt.Step())
- return false;
- page_size = stmt.ColumnInt(0);
-
- stmt.Assign(db.GetUniqueStatement(
- "SELECT rootpage FROM sqlite_master WHERE name = ?"));
- stmt.BindString(0, "sub_prefix");
- if (!stmt.Step())
- return false;
- root_page = stmt.ColumnInt(0);
-
- // The page numbers are 1-based.
- const size_t root_page_offset = (root_page - 1) * page_size;
-
- // Corrupt the file by overwriting the table's root page.
- FILE* fp = file_util::OpenFile(filename, "r+");
- if (!fp)
- return false;
-
- file_util::ScopedFILE file_closer(fp);
- if (fseek(fp, root_page_offset, SEEK_SET) == -1)
- return false;
-
- for (size_t i = 0; i < page_size; ++i) {
- fputc('!', fp); // Character experimentally verified.
- }
-
- // Close the file manually because if there is an error in the
- // close, it's likely because the data could not be flushed to the
- // file.
- if (!file_util::CloseFile(file_closer.release()))
- return false;
-
- return true;
-}
-
} // namespace
class SafeBrowsingDatabaseTest : public PlatformTest {
@@ -1088,84 +1036,6 @@ TEST_F(SafeBrowsingDatabaseTest, HashCaching) {
// corruption is detected in the midst of the update.
// TODO(shess): Disabled until ScopedLogMessageIgnorer resolved.
// http://crbug.com/56448
-TEST_F(SafeBrowsingDatabaseTest, DISABLED_SqliteCorruptionHandling) {
- // Re-create the database in a captive message loop so that we can
- // influence task-posting. Database specifically needs to the
- // SQLite-backed.
- database_.reset();
- MessageLoop loop(MessageLoop::TYPE_DEFAULT);
- SafeBrowsingStoreSqlite* store = new SafeBrowsingStoreSqlite();
- database_.reset(new SafeBrowsingDatabaseNew(store, NULL));
- database_->Init(database_filename_);
-
- // This will cause an empty database to be created.
- std::vector<SBListChunkRanges> lists;
- EXPECT_TRUE(database_->UpdateStarted(&lists));
- database_->UpdateFinished(true);
-
- // Create a sub chunk to insert.
- SBChunkList chunks;
- SBChunk chunk;
- SBChunkHost host;
- host.host = Sha256Prefix("www.subbed.com/");
- host.entry = SBEntry::Create(SBEntry::SUB_PREFIX, 1);
- host.entry->set_chunk_id(7);
- host.entry->SetChunkIdAtPrefix(0, 19);
- host.entry->SetPrefixAt(0, Sha256Prefix("www.subbed.com/notevil1.html"));
- chunk.chunk_number = 7;
- chunk.is_add = false;
- chunk.hosts.clear();
- chunk.hosts.push_back(host);
- chunks.clear();
- chunks.push_back(chunk);
-
- // Corrupt the |sub_prefix| table.
- ASSERT_TRUE(CorruptSqliteTable(database_filename_, "sub_prefix"));
-
- {
- // The following code will cause DCHECKs, so suppress the crashes.
- ScopedLogMessageIgnorer ignorer;
-
- // Start an update. The insert will fail due to corruption.
- EXPECT_TRUE(database_->UpdateStarted(&lists));
- VLOG(1) << "Expect failed check on: sqlite error 11";
- database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
-
- // Database file still exists until the corruption handler has run.
- EXPECT_TRUE(file_util::PathExists(database_filename_));
-
- // Flush through the corruption-handler task.
- VLOG(1) << "Expect failed check on: SafeBrowsing database reset";
- MessageLoop::current()->RunAllPending();
- }
-
- // Database file should not exist.
- EXPECT_FALSE(file_util::PathExists(database_filename_));
-
- // Finish the transaction. This should short-circuit, so no
- // DCHECKs.
- database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
- database_->UpdateFinished(true);
-
- // Flush through any posted tasks.
- MessageLoop::current()->RunAllPending();
-
- // Database file should still not exist.
- EXPECT_FALSE(file_util::PathExists(database_filename_));
-
- // Run the update again successfully.
- EXPECT_TRUE(database_->UpdateStarted(&lists));
- database_->InsertChunks(safe_browsing_util::kMalwareList, chunks);
- database_->UpdateFinished(true);
- EXPECT_TRUE(file_util::PathExists(database_filename_));
-
- database_.reset();
-}
-
-// Test that corrupt databases are appropriately handled, even if the
-// corruption is detected in the midst of the update.
-// TODO(shess): Disabled until ScopedLogMessageIgnorer resolved.
-// http://crbug.com/56448
TEST_F(SafeBrowsingDatabaseTest, DISABLED_FileCorruptionHandling) {
// Re-create the database in a captive message loop so that we can
// influence task-posting. Database specifically needs to the
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 85255e5..ec05f5d 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -348,8 +348,8 @@ class SafeBrowsingService
// Used for issuing only one GetHash request for a given prefix.
GetHashRequests gethash_requests_;
- // The sqlite database. We don't use a scoped_ptr because it needs to be
- // destructed on a different thread than this object.
+ // The persistent database. We don't use a scoped_ptr because it
+ // needs to be destructed on a different thread than this object.
SafeBrowsingDatabase* database_;
// Lock used to prevent possible data races due to compiler optimizations.
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.cc b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
index cc8ae87..5171426 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
@@ -8,9 +8,6 @@
#include "base/metrics/histogram.h"
#include "base/md5.h"
-// TODO(shess): Remove after migration.
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
-
namespace {
// NOTE(shess): kFileMagic should not be a byte-wise palindrome, so
@@ -261,16 +258,13 @@ bool SafeBrowsingStoreFile::Delete() {
return false;
}
- // Also make sure any SQLite data is deleted. This should only be
- // needed if a journal file is left from a crash and the database is
- // reset before SQLite gets a chance to straighten things out.
- // TODO(shess): Remove after migration.
- SafeBrowsingStoreSqlite old_store;
- old_store.Init(
- filename_,
- NewCallback(this, &SafeBrowsingStoreFile::HandleCorruptDatabase));
- if (!old_store.Delete())
- return false;
+ // With SQLite support gone, one way to get to this code is if the
+ // existing file is a SQLite file. Make sure the journal file is
+ // also removed.
+ const FilePath journal_filename(
+ filename_.value() + FILE_PATH_LITERAL("-journal"));
+ if (file_util::PathExists(journal_filename))
+ file_util::Delete(journal_filename, false);
return true;
}
@@ -344,27 +338,17 @@ bool SafeBrowsingStoreFile::OnCorruptDatabase() {
return false;
}
-void SafeBrowsingStoreFile::HandleCorruptDatabase() {
- if (!corruption_seen_)
- RecordFormatEvent(FORMAT_EVENT_SQLITE_CORRUPT);
- corruption_seen_ = true;
-
- if (corruption_callback_.get())
- corruption_callback_->Run();
-}
-
bool SafeBrowsingStoreFile::Close() {
ClearUpdateBuffers();
// Make sure the files are closed.
file_.reset();
new_file_.reset();
- old_store_.reset();
return true;
}
bool SafeBrowsingStoreFile::BeginUpdate() {
- DCHECK(!file_.get() && !new_file_.get() && !old_store_.get());
+ DCHECK(!file_.get() && !new_file_.get());
// Structures should all be clear unless something bad happened.
DCHECK(add_chunks_cache_.empty());
@@ -412,32 +396,10 @@ bool SafeBrowsingStoreFile::BeginUpdate() {
RecordFormatEvent(FORMAT_EVENT_FOUND_UNKNOWN);
}
- // Something about having the file open causes a problem with
- // SQLite opening it. Perhaps PRAGMA locking_mode = EXCLUSIVE?
+ // Close the file so that it can be deleted.
file.reset();
- // Magic numbers didn't match, maybe it's a SQLite database.
- scoped_ptr<SafeBrowsingStoreSqlite>
- sqlite_store(new SafeBrowsingStoreSqlite());
- sqlite_store->Init(
- filename_,
- NewCallback(this, &SafeBrowsingStoreFile::HandleCorruptDatabase));
- if (!sqlite_store->BeginUpdate())
- return OnCorruptDatabase();
-
- // Pull chunks-seen data into local structures, rather than
- // optionally wiring various calls through to the SQLite store.
- std::vector<int32> chunks;
- sqlite_store->GetAddChunks(&chunks);
- add_chunks_cache_.insert(chunks.begin(), chunks.end());
-
- sqlite_store->GetSubChunks(&chunks);
- sub_chunks_cache_.insert(chunks.begin(), chunks.end());
-
- new_file_.swap(new_file);
- old_store_.swap(sqlite_store);
-
- return true;
+ return OnCorruptDatabase();
}
// TODO(shess): Under POSIX it is possible that this could size a
@@ -489,7 +451,7 @@ bool SafeBrowsingStoreFile::DoUpdate(
const std::set<SBPrefix>& prefix_misses,
std::vector<SBAddPrefix>* add_prefixes_result,
std::vector<SBAddFullHash>* add_full_hashes_result) {
- DCHECK(old_store_.get() || file_.get() || empty_);
+ DCHECK(file_.get() || empty_);
DCHECK(new_file_.get());
CHECK(add_prefixes_result);
CHECK(add_full_hashes_result);
@@ -499,29 +461,8 @@ bool SafeBrowsingStoreFile::DoUpdate(
std::vector<SBAddFullHash> add_full_hashes;
std::vector<SBSubFullHash> sub_full_hashes;
- // Read |old_store_| into the vectors.
- if (old_store_.get()) {
- // Push deletions to |old_store_| so they can be applied to the
- // data being read.
- for (base::hash_set<int32>::const_iterator iter = add_del_cache_.begin();
- iter != add_del_cache_.end(); ++iter) {
- old_store_->DeleteAddChunk(*iter);
- }
- for (base::hash_set<int32>::const_iterator iter = sub_del_cache_.begin();
- iter != sub_del_cache_.end(); ++iter) {
- old_store_->DeleteSubChunk(*iter);
- }
-
- if (!old_store_->ReadAddPrefixes(&add_prefixes) ||
- !old_store_->ReadSubPrefixes(&sub_prefixes) ||
- !old_store_->ReadAddHashes(&add_full_hashes) ||
- !old_store_->ReadSubHashes(&sub_full_hashes))
- return OnCorruptDatabase();
-
- // Do not actually update the old store.
- if (!old_store_->CancelUpdate())
- return OnCorruptDatabase();
- } else if (!empty_) {
+ // Read original data into the vectors.
+ if (!empty_) {
DCHECK(file_.get());
if (!FileRewind(file_.get()))
@@ -677,19 +618,9 @@ bool SafeBrowsingStoreFile::DoUpdate(
// Close the file handle and swizzle the file into place.
new_file_.reset();
- if (old_store_.get()) {
- const bool deleted = old_store_->Delete();
- old_store_.reset();
- if (!deleted) {
- RecordFormatEvent(FORMAT_EVENT_SQLITE_DELETE_FAILED);
- return false;
- }
- RecordFormatEvent(FORMAT_EVENT_SQLITE_DELETED);
- } else {
- if (!file_util::Delete(filename_, false) &&
- file_util::PathExists(filename_))
- return false;
- }
+ if (!file_util::Delete(filename_, false) &&
+ file_util::PathExists(filename_))
+ return false;
const FilePath new_filename = TemporaryFileForFilename(filename_);
if (!file_util::Move(new_filename, filename_))
@@ -724,13 +655,11 @@ bool SafeBrowsingStoreFile::FinishUpdate(
DCHECK(!new_file_.get());
DCHECK(!file_.get());
- DCHECK(!old_store_.get());
return Close();
}
bool SafeBrowsingStoreFile::CancelUpdate() {
- old_store_.reset();
return Close();
}
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.h b/chrome/browser/safe_browsing/safe_browsing_store_file.h
index 02a2920..88e1b2f 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.h
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.h
@@ -14,12 +14,6 @@
#include "base/callback.h"
#include "base/file_util.h"
-// TODO(shess): Data is migrated from SafeBrowsingStoreSqlite as part
-// of the next update. That way everyone doesn't pull a new database
-// when the code rolls out (and the migration code isn't gnarly).
-// After substantially everyone has migrated, the migration code can
-// be removed. Make sure that it deletes any journal file.
-
// Implement SafeBrowsingStore in terms of a flat file. The file
// format is pretty literal:
//
@@ -110,9 +104,6 @@
// often, consider retaining the last known-good file for recovery
// purposes, rather than deleting it.
-// TODO(shess): Remove after migration.
-class SafeBrowsingStoreSqlite;
-
class SafeBrowsingStoreFile : public SafeBrowsingStore {
public:
SafeBrowsingStoreFile();
@@ -176,7 +167,7 @@ class SafeBrowsingStoreFile : public SafeBrowsingStore {
enum FormatEventType {
// Corruption detected, broken down by file format.
FORMAT_EVENT_FILE_CORRUPT,
- FORMAT_EVENT_SQLITE_CORRUPT,
+ FORMAT_EVENT_SQLITE_CORRUPT, // Obsolete
// The type of format found in the file. The expected case (new
// file format) is intentionally not covered.
@@ -186,8 +177,8 @@ class SafeBrowsingStoreFile : public SafeBrowsingStore {
// The number of SQLite-format files deleted should be the same as
// FORMAT_EVENT_FOUND_SQLITE. It can differ if the delete fails,
// or if a failure prevents the update from succeeding.
- FORMAT_EVENT_SQLITE_DELETED,
- FORMAT_EVENT_SQLITE_DELETE_FAILED,
+ FORMAT_EVENT_SQLITE_DELETED, // Obsolete
+ FORMAT_EVENT_SQLITE_DELETE_FAILED, // Obsolete
// Found and deleted (or failed to delete) the ancient "Safe
// Browsing" file.
@@ -263,11 +254,6 @@ class SafeBrowsingStoreFile : public SafeBrowsingStore {
file_util::ScopedFILE new_file_;
bool empty_;
- // If the main file existed, but was an SQLite store, this is a
- // handle to it.
- // TODO(shess): Remove this (and all references) after migration.
- scoped_ptr<SafeBrowsingStoreSqlite> old_store_;
-
// Cache of chunks which have been seen. Loaded from the database
// on BeginUpdate() so that it can be queried during the
// transaction.
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
index 01977a7..39fe53a 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file_unittest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include "chrome/browser/safe_browsing/safe_browsing_store_file.h"
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
#include "base/callback.h"
#include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
@@ -146,169 +145,4 @@ TEST_F(SafeBrowsingStoreFileTest, DetectsCorruption) {
EXPECT_TRUE(corruption_detected_);
}
-// Info to build a trivial store for migration testing.
-const int kAddChunk1 = 1;
-const int kAddChunk2 = 3;
-const int kAddChunk3 = 5;
-const int kSubChunk1 = 2;
-const int kSubChunk2 = 4;
-const SBFullHash kHash1 = SBFullHashFromString("one");
-const SBFullHash kHash2 = SBFullHashFromString("two");
-const SBPrefix kPrefix1 = kHash1.prefix;
-const SBPrefix kPrefix2 = kHash2.prefix;
-const SBPrefix kPrefix3 = SBFullHashFromString("three").prefix;
-const SBPrefix kPrefix4 = SBFullHashFromString("four").prefix;
-const SBPrefix kPrefix5 = SBFullHashFromString("five").prefix;
-
-// Load the store with some data.
-void LoadStore(SafeBrowsingStore* store) {
- EXPECT_TRUE(store->BeginUpdate());
- EXPECT_TRUE(store->BeginChunk());
-
- store->SetAddChunk(kAddChunk1);
- store->SetSubChunk(kSubChunk1);
- store->SetAddChunk(kAddChunk2);
-
- EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kPrefix1));
- EXPECT_TRUE(store->WriteAddPrefix(kAddChunk1, kPrefix2));
- EXPECT_TRUE(store->WriteAddPrefix(kAddChunk2, kPrefix3));
- EXPECT_TRUE(store->WriteSubPrefix(kSubChunk1, kAddChunk3, kPrefix4));
- EXPECT_TRUE(store->WriteAddHash(kAddChunk1, base::Time::Now(), kHash1));
- EXPECT_TRUE(store->WriteSubHash(kSubChunk1, kAddChunk1, kHash2));
-
- EXPECT_TRUE(store->FinishChunk());
-
- std::vector<SBAddFullHash> pending_adds;
- std::set<SBPrefix> prefix_misses;
- std::vector<SBAddPrefix> add_prefixes;
- std::vector<SBAddFullHash> add_hashes;
- EXPECT_TRUE(store->FinishUpdate(pending_adds, prefix_misses,
- &add_prefixes, &add_hashes));
- EXPECT_EQ(3U, add_prefixes.size());
- EXPECT_EQ(1U, add_hashes.size());
-
- // Make sure add prefixes are correct.
- std::vector<SBAddPrefix> in_store_add_prefixes;
- EXPECT_TRUE(store->GetAddPrefixes(&in_store_add_prefixes));
- ASSERT_EQ(3U, in_store_add_prefixes.size());
- EXPECT_EQ(kPrefix1, in_store_add_prefixes[0].prefix);
- EXPECT_EQ(kAddChunk1, in_store_add_prefixes[0].chunk_id);
- EXPECT_EQ(kPrefix2, in_store_add_prefixes[1].prefix);
- EXPECT_EQ(kAddChunk1, in_store_add_prefixes[1].chunk_id);
- EXPECT_EQ(kPrefix3, in_store_add_prefixes[2].prefix);
- EXPECT_EQ(kAddChunk2, in_store_add_prefixes[2].chunk_id);
-}
-
-// Verify that the store looks like what results from LoadStore(), and
-// update it.
-void UpdateStore(SafeBrowsingStore* store) {
- EXPECT_TRUE(store->BeginUpdate());
- EXPECT_TRUE(store->BeginChunk());
-
- // The chunks in the database should be the same.
- std::vector<int> add_chunks;
- store->GetAddChunks(&add_chunks);
- ASSERT_EQ(2U, add_chunks.size());
- EXPECT_EQ(kAddChunk1, add_chunks[0]);
- EXPECT_EQ(kAddChunk2, add_chunks[1]);
-
- std::vector<int> sub_chunks;
- store->GetSubChunks(&sub_chunks);
- ASSERT_EQ(1U, sub_chunks.size());
- EXPECT_EQ(kSubChunk1, sub_chunks[0]);
-
- EXPECT_TRUE(store->CheckAddChunk(kAddChunk1));
- EXPECT_TRUE(store->CheckSubChunk(kSubChunk1));
- EXPECT_TRUE(store->CheckAddChunk(kAddChunk2));
-
- EXPECT_FALSE(store->CheckAddChunk(kAddChunk3));
- store->SetAddChunk(kAddChunk3);
- // This one already has a sub.
- EXPECT_TRUE(store->WriteAddPrefix(kAddChunk3, kPrefix4));
- EXPECT_TRUE(store->WriteAddPrefix(kAddChunk3, kPrefix5));
-
- EXPECT_FALSE(store->CheckSubChunk(kSubChunk2));
- store->SetSubChunk(kSubChunk2);
- EXPECT_TRUE(store->WriteSubPrefix(kSubChunk2, kAddChunk1, kPrefix1));
-
- EXPECT_TRUE(store->FinishChunk());
-
- store->DeleteAddChunk(kAddChunk2);
-
- std::vector<SBAddFullHash> pending_adds;
- std::set<SBPrefix> prefix_misses;
- std::vector<SBAddPrefix> add_prefixes;
- std::vector<SBAddFullHash> add_hashes;
- EXPECT_TRUE(store->FinishUpdate(pending_adds, prefix_misses,
- &add_prefixes, &add_hashes));
- EXPECT_EQ(2U, add_prefixes.size());
- EXPECT_EQ(0U, add_hashes.size());
-}
-
-// Verify that the expected UpdateStore() data is present.
-void CheckStore(SafeBrowsingStore* store) {
- EXPECT_TRUE(store->BeginUpdate());
-
- // The chunks in the database should be the same.
- std::vector<int> add_chunks;
- store->GetAddChunks(&add_chunks);
- ASSERT_EQ(2U, add_chunks.size());
- EXPECT_EQ(kAddChunk1, add_chunks[0]);
- EXPECT_EQ(kAddChunk3, add_chunks[1]);
-
- std::vector<int> sub_chunks;
- store->GetSubChunks(&sub_chunks);
- ASSERT_EQ(2U, sub_chunks.size());
- EXPECT_EQ(kSubChunk1, sub_chunks[0]);
- EXPECT_EQ(kSubChunk2, sub_chunks[1]);
-
- EXPECT_TRUE(store->CancelUpdate());
-
- // Make sure add prefixes are correct.
- std::vector<SBAddPrefix> add_prefixes;
- EXPECT_TRUE(store->GetAddPrefixes(&add_prefixes));
- ASSERT_EQ(2U, add_prefixes.size());
- EXPECT_EQ(kPrefix2, add_prefixes[0].prefix);
- EXPECT_EQ(kAddChunk1, add_prefixes[0].chunk_id);
- EXPECT_EQ(kPrefix5, add_prefixes[1].prefix);
- EXPECT_EQ(kAddChunk3, add_prefixes[1].chunk_id);
-}
-
-// Verify that the migration sequence works as expected in the
-// non-migration cases.
-TEST_F(SafeBrowsingStoreFileTest, MigrateBaselineFile) {
- LoadStore(store_.get());
- UpdateStore(store_.get());
- CheckStore(store_.get());
-}
-TEST_F(SafeBrowsingStoreFileTest, MigrateBaselineSqlite) {
- SafeBrowsingStoreSqlite sqlite_store;
- sqlite_store.Init(filename_, NULL);
-
- LoadStore(&sqlite_store);
- UpdateStore(&sqlite_store);
- CheckStore(&sqlite_store);
-}
-
-// The sequence should work exactly the same when we migrate from
-// SQLite to file.
-TEST_F(SafeBrowsingStoreFileTest, Migrate) {
- // No existing store.
- EXPECT_FALSE(file_util::PathExists(filename_));
-
- {
- SafeBrowsingStoreSqlite sqlite_store;
- sqlite_store.Init(filename_, NULL);
-
- LoadStore(&sqlite_store);
- }
-
- // At this point |filename_| references a SQLite store.
- EXPECT_TRUE(file_util::PathExists(filename_));
-
- // Update and check using a file store.
- UpdateStore(store_.get());
- CheckStore(store_.get());
-}
-
} // namespace
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_sqlite.cc b/chrome/browser/safe_browsing/safe_browsing_store_sqlite.cc
deleted file mode 100644
index c9cf026..0000000
--- a/chrome/browser/safe_browsing/safe_browsing_store_sqlite.cc
+++ /dev/null
@@ -1,749 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
-
-#include <string>
-
-#include "base/callback.h"
-#include "base/file_util.h"
-#include "base/metrics/histogram.h"
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/common/sqlite_compiled_statement.h"
-#include "chrome/common/sqlite_utils.h"
-
-namespace {
-
-// Database version. If this is different than what's stored on disk, the
-// database is reset.
-const int kDatabaseVersion = 6;
-
-// Used for reading full hashes from the database.
-SBFullHash ReadFullHash(SqliteCompiledStatement* statement, int column) {
- std::vector<unsigned char> blob;
- (*statement)->column_blob_as_vector(column, &blob);
-
- SBFullHash ret;
- DCHECK_EQ(blob.size(), sizeof(ret));
- memcpy(ret.full_hash, &blob[0], sizeof(ret));
- return ret;
-}
-
-void DeleteChunksFromSet(const base::hash_set<int32>& deleted,
- std::set<int32>* chunks) {
- for (std::set<int32>::iterator iter = chunks->begin();
- iter != chunks->end();) {
- std::set<int32>::iterator prev = iter++;
- if (deleted.count(*prev) > 0)
- chunks->erase(prev);
- }
-}
-
-} // namespace
-
-SafeBrowsingStoreSqlite::SafeBrowsingStoreSqlite()
- : db_(NULL),
- statement_cache_(NULL),
- insert_transaction_(NULL) {
-}
-SafeBrowsingStoreSqlite::~SafeBrowsingStoreSqlite() {
- Close();
-}
-
-bool SafeBrowsingStoreSqlite::Delete() {
- // The file must be closed, both so that the journal file is deleted
- // by SQLite, and because open files cannot be deleted on Windows.
- if (!Close()) {
- NOTREACHED();
- return false;
- }
-
- // Just in case, delete the journal file, because associating the
- // wrong journal file with a database is very bad.
- const FilePath journal_file = JournalFileForFilename(filename_);
- if (!file_util::Delete(journal_file, false) &&
- file_util::PathExists(journal_file)) {
- NOTREACHED();
- return false;
- }
-
- if (!file_util::Delete(filename_, false) &&
- file_util::PathExists(filename_)) {
- NOTREACHED();
- return false;
- }
-
- return true;
-}
-
-void SafeBrowsingStoreSqlite::Init(const FilePath& filename,
- Callback0::Type* corruption_callback) {
- filename_ = filename;
- corruption_callback_.reset(corruption_callback);
-}
-
-bool SafeBrowsingStoreSqlite::BeginChunk() {
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::GetAddPrefixes(
- std::vector<SBAddPrefix>* add_prefixes) {
- add_prefixes->clear();
- if (!Open()) return false;
- bool ret = ReadAddPrefixes(add_prefixes);
- Close();
- return ret;
-}
-
-bool SafeBrowsingStoreSqlite::WriteAddPrefix(int32 chunk_id, SBPrefix prefix) {
- const std::vector<SBAddPrefix> prefixes(1, SBAddPrefix(chunk_id, prefix));
- return WriteAddPrefixes(prefixes);
-}
-
-bool SafeBrowsingStoreSqlite::WriteAddHash(int32 chunk_id,
- base::Time receive_time,
- const SBFullHash& full_hash) {
- const std::vector<SBAddFullHash>
- hashes(1, SBAddFullHash(chunk_id, receive_time, full_hash));
- return WriteAddHashes(hashes);
-}
-
-bool SafeBrowsingStoreSqlite::WriteSubPrefix(int32 chunk_id,
- int32 add_chunk_id,
- SBPrefix prefix) {
- const std::vector<SBSubPrefix>
- prefixes(1, SBSubPrefix(chunk_id, add_chunk_id, prefix));
- return WriteSubPrefixes(prefixes);
-}
-
-bool SafeBrowsingStoreSqlite::WriteSubHash(int32 chunk_id,
- int32 add_chunk_id,
- const SBFullHash& full_hash) {
- const std::vector<SBSubFullHash>
- hashes(1, SBSubFullHash(chunk_id, add_chunk_id, full_hash));
- return WriteSubHashes(hashes);
-}
-
-bool SafeBrowsingStoreSqlite::FinishChunk() {
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::OnCorruptDatabase() {
- if (corruption_callback_.get())
- corruption_callback_->Run();
- return false;
-}
-
-bool SafeBrowsingStoreSqlite::Open() {
- // This case should never happen, but if it does we shouldn't leak
- // handles.
- if (db_) {
- NOTREACHED() << " Database was already open in Open().";
- return true;
- }
-
- if (sqlite_utils::OpenSqliteDb(filename_, &db_) != SQLITE_OK) {
- sqlite3_close(db_);
- db_ = NULL;
- return false;
- }
-
- // Run the database in exclusive mode. Nobody else should be accessing the
- // database while we're running, and this will give somewhat improved perf.
- ExecSql("PRAGMA locking_mode = EXCLUSIVE");
- ExecSql("PRAGMA cache_size = 100");
-
- statement_cache_.reset(new SqliteStatementCache(db_));
-
- if (!sqlite_utils::DoesSqliteTableExist(db_, "add_prefix"))
- return SetupDatabase();
-
- return CheckCompatibleVersion();
-}
-
-bool SafeBrowsingStoreSqlite::ExecSql(const char* sql) {
- DCHECK(db_);
-
- int rv = sqlite3_exec(db_, sql, NULL, NULL, NULL);
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_OK);
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::Close() {
- if (!db_)
- return true;
-
- add_chunks_cache_.clear();
- sub_chunks_cache_.clear();
-
- add_del_cache_.clear();
- sub_del_cache_.clear();
-
- insert_transaction_.reset();
- statement_cache_.reset(); // Must free statements before closing DB.
- bool result = sqlite3_close(db_) == SQLITE_OK;
- db_ = NULL;
-
- return result;
-}
-
-bool SafeBrowsingStoreSqlite::CreateTables() {
- DCHECK(db_);
-
- // Store 32 bit add prefixes here.
- if (!ExecSql("CREATE TABLE add_prefix ("
- " chunk INTEGER,"
- " prefix INTEGER"
- ")"))
- return false;
-
- // Store 32 bit sub prefixes here.
- if (!ExecSql("CREATE TABLE sub_prefix ("
- " chunk INTEGER,"
- " add_chunk INTEGER,"
- " prefix INTEGER"
- ")"))
- return false;
-
- // Store 256 bit add full hashes (and GetHash results) here.
- if (!ExecSql("CREATE TABLE add_full_hash ("
- " chunk INTEGER,"
- " prefix INTEGER,"
- " receive_time INTEGER,"
- " full_hash BLOB"
- ")"))
- return false;
-
- // Store 256 bit sub full hashes here.
- if (!ExecSql("CREATE TABLE sub_full_hash ("
- " chunk INTEGER,"
- " add_chunk INTEGER,"
- " prefix INTEGER,"
- " full_hash BLOB"
- ")"))
- return false;
-
- // Store all the add and sub chunk numbers we receive. We cannot
- // just rely on the prefix tables to generate these lists, since
- // some chunks will have zero entries (and thus no prefixes), or
- // potentially an add chunk can have all of its entries sub'd
- // without receiving an AddDel, or a sub chunk might have been
- // entirely consumed by adds. In these cases, we still have to
- // report the chunk number but it will not have any prefixes in the
- // prefix tables.
- //
- // TODO(paulg): Investigate storing the chunks as a string of
- // ChunkRanges, one string for each of phish-add, phish-sub,
- // malware-add, malware-sub. This might be better performance when
- // the number of chunks is large, and is the natural format for the
- // update request.
- if (!ExecSql("CREATE TABLE add_chunks ("
- " chunk INTEGER PRIMARY KEY"
- ")"))
- return false;
-
- if (!ExecSql("CREATE TABLE sub_chunks ("
- " chunk INTEGER PRIMARY KEY"
- ")"))
- return false;
-
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::SetupDatabase() {
- DCHECK(db_);
-
- SQLTransaction transaction(db_);
- if (transaction.Begin() != SQLITE_OK) {
- NOTREACHED();
- return false;
- }
-
- if (!CreateTables())
- return false;
-
- // PRAGMA does not support bind parameters...
- const std::string version =
- StringPrintf("PRAGMA user_version = %d", kDatabaseVersion);
- if (!ExecSql(version.c_str()))
- return false;
-
- if (transaction.Commit() != SQLITE_OK)
- return false;
-
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::CheckCompatibleVersion() {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "PRAGMA user_version");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int result = statement->step();
- if (result != SQLITE_ROW)
- return false;
-
- return statement->column_int(0) == kDatabaseVersion;
-}
-
-bool SafeBrowsingStoreSqlite::ReadAddChunks() {
- DCHECK(db_);
-
- add_chunks_cache_.clear();
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk FROM add_chunks");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- add_chunks_cache_.insert(statement->column_int(0));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK_EQ(rv, SQLITE_DONE);
- return rv == SQLITE_DONE;
-}
-
-bool SafeBrowsingStoreSqlite::WriteAddChunks() {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO add_chunks (chunk) VALUES (?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::set<int32>::const_iterator iter = add_chunks_cache_.begin();
- iter != add_chunks_cache_.end(); ++iter) {
- statement->bind_int(0, *iter);
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ReadSubChunks() {
- DCHECK(db_);
-
- sub_chunks_cache_.clear();
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk FROM sub_chunks");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- sub_chunks_cache_.insert(statement->column_int(0));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- return rv == SQLITE_DONE;
-}
-
-bool SafeBrowsingStoreSqlite::WriteSubChunks() {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO sub_chunks (chunk) VALUES (?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::set<int32>::const_iterator iter = sub_chunks_cache_.begin();
- iter != sub_chunks_cache_.end(); ++iter) {
- statement->bind_int(0, *iter);
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ReadAddPrefixes(
- std::vector<SBAddPrefix>* add_prefixes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk, prefix FROM add_prefix");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- const int32 chunk_id = statement->column_int(0);
- const SBPrefix prefix = statement->column_int(1);
- add_prefixes->push_back(SBAddPrefix(chunk_id, prefix));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK_EQ(rv, SQLITE_DONE);
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::WriteAddPrefixes(
- const std::vector<SBAddPrefix>& add_prefixes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO add_prefix "
- "(chunk, prefix) VALUES (?,?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::vector<SBAddPrefix>::const_iterator iter = add_prefixes.begin();
- iter != add_prefixes.end(); ++iter) {
- statement->bind_int(0, iter->chunk_id);
- statement->bind_int(1, iter->prefix);
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ReadSubPrefixes(
- std::vector<SBSubPrefix>* sub_prefixes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk, add_chunk, prefix "
- "FROM sub_prefix");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- const int32 chunk_id = statement->column_int(0);
- const int32 add_chunk_id = statement->column_int(1);
- const SBPrefix add_prefix = statement->column_int(2);
- sub_prefixes->push_back(SBSubPrefix(chunk_id, add_chunk_id, add_prefix));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK_EQ(rv, SQLITE_DONE);
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::WriteSubPrefixes(
- const std::vector<SBSubPrefix>& sub_prefixes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO sub_prefix "
- "(chunk, add_chunk, prefix) VALUES (?,?, ?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::vector<SBSubPrefix>::const_iterator iter = sub_prefixes.begin();
- iter != sub_prefixes.end(); ++iter) {
- statement->bind_int(0, iter->chunk_id);
- statement->bind_int(1, iter->add_chunk_id);
- statement->bind_int(2, iter->add_prefix);
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ReadAddHashes(
- std::vector<SBAddFullHash>* add_hashes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk, prefix, receive_time, full_hash "
- "FROM add_full_hash");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- const int32 chunk_id = statement->column_int(0);
- // NOTE: Legacy format duplicated |hash.prefix| in column 1.
- const SBPrefix prefix = statement->column_int(1);
- const int32 received = statement->column_int(2);
- const SBFullHash full_hash = ReadFullHash(&statement, 3);
- DCHECK_EQ(prefix, full_hash.prefix);
- add_hashes->push_back(SBAddFullHash(chunk_id, received, full_hash));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK_EQ(rv, SQLITE_DONE);
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::WriteAddHashes(
- const std::vector<SBAddFullHash>& add_hashes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO add_full_hash "
- "(chunk, prefix, receive_time, full_hash) "
- "VALUES (?,?, ?, ?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::vector<SBAddFullHash>::const_iterator iter = add_hashes.begin();
- iter != add_hashes.end(); ++iter) {
- // NOTE: Legacy format duplicated |hash.prefix| in column 1.
- statement->bind_int(0, iter->chunk_id);
- statement->bind_int(1, iter->full_hash.prefix);
- statement->bind_int(2, iter->received);
- statement->bind_blob(3, iter->full_hash.full_hash,
- sizeof(iter->full_hash.full_hash));
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ReadSubHashes(
- std::vector<SBSubFullHash>* sub_hashes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "SELECT chunk, add_chunk, prefix, full_hash "
- "FROM sub_full_hash");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- int rv;
- while ((rv = statement->step()) == SQLITE_ROW) {
- const int32 chunk_id = statement->column_int(0);
- // NOTE: Legacy format duplicated |hash.prefix| in column 2.
- const int32 add_chunk_id = statement->column_int(1);
- const SBPrefix add_prefix = statement->column_int(2);
- const SBFullHash full_hash = ReadFullHash(&statement, 3);
- DCHECK_EQ(add_prefix, full_hash.prefix);
- sub_hashes->push_back(SBSubFullHash(chunk_id, add_chunk_id, full_hash));
- }
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK_EQ(rv, SQLITE_DONE);
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::WriteSubHashes(
- const std::vector<SBSubFullHash>& sub_hashes) {
- DCHECK(db_);
-
- SQLITE_UNIQUE_STATEMENT(statement, *statement_cache_,
- "INSERT INTO sub_full_hash "
- "(chunk, add_chunk, prefix, full_hash) "
- "VALUES (?,?,?,?)");
- if (!statement.is_valid()) {
- NOTREACHED();
- return false;
- }
-
- for (std::vector<SBSubFullHash>::const_iterator iter = sub_hashes.begin();
- iter != sub_hashes.end(); ++iter) {
- // NOTE: Legacy format duplicated |hash.prefix| in column 2.
- statement->bind_int(0, iter->chunk_id);
- statement->bind_int(1, iter->add_chunk_id);
- statement->bind_int(2, iter->full_hash.prefix);
- statement->bind_blob(3, iter->full_hash.full_hash,
- sizeof(iter->full_hash.full_hash));
- int rv = statement->step();
- if (rv == SQLITE_CORRUPT)
- return OnCorruptDatabase();
- DCHECK(rv == SQLITE_DONE);
- statement->reset();
- }
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::ResetTables() {
- DCHECK(db_);
-
- if (!ExecSql("DELETE FROM add_prefix") ||
- !ExecSql("DELETE FROM sub_prefix") ||
- !ExecSql("DELETE FROM add_full_hash") ||
- !ExecSql("DELETE FROM sub_full_hash") ||
- !ExecSql("DELETE FROM add_chunks") ||
- !ExecSql("DELETE FROM sub_chunks"))
- return false;
-
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::BeginUpdate() {
- DCHECK(!db_);
-
- if (!Open())
- return false;
-
- insert_transaction_.reset(new SQLTransaction(db_));
- if (insert_transaction_->Begin() != SQLITE_OK) {
- DCHECK(false) << "Safe browsing store couldn't start transaction";
- Close();
- return false;
- }
-
- if (!ReadAddChunks() || !ReadSubChunks())
- return false;
-
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::DoUpdate(
- const std::vector<SBAddFullHash>& pending_adds,
- std::vector<SBAddPrefix>* add_prefixes_result,
- std::vector<SBAddFullHash>* add_full_hashes_result) {
- DCHECK(db_);
-
- std::vector<SBAddPrefix> add_prefixes;
- std::vector<SBAddFullHash> add_full_hashes;
- std::vector<SBSubPrefix> sub_prefixes;
- std::vector<SBSubFullHash> sub_full_hashes;
-
- if (!ReadAddPrefixes(&add_prefixes) ||
- !ReadAddHashes(&add_full_hashes) ||
- !ReadSubPrefixes(&sub_prefixes) ||
- !ReadSubHashes(&sub_full_hashes))
- return false;
-
- // Append items from |pending_adds|.
- add_full_hashes.insert(add_full_hashes.end(),
- pending_adds.begin(), pending_adds.end());
-
- // Knock the subs from the adds and process deleted chunks.
- SBProcessSubs(&add_prefixes, &sub_prefixes,
- &add_full_hashes, &sub_full_hashes,
- add_del_cache_, sub_del_cache_);
-
- DeleteChunksFromSet(add_del_cache_, &add_chunks_cache_);
- DeleteChunksFromSet(sub_del_cache_, &sub_chunks_cache_);
-
- // Clear the existing tables before rewriting them.
- if (!ResetTables())
- return false;
-
- if (!WriteAddChunks() ||
- !WriteSubChunks() ||
- !WriteAddPrefixes(add_prefixes) ||
- !WriteSubPrefixes(sub_prefixes) ||
- !WriteAddHashes(add_full_hashes) ||
- !WriteSubHashes(sub_full_hashes))
- return false;
-
- // Commit all the changes to the database.
- int rv = insert_transaction_->Commit();
- if (rv != SQLITE_OK) {
- NOTREACHED() << "SafeBrowsing update transaction failed to commit.";
- UMA_HISTOGRAM_COUNTS("SB2.FailedUpdate", 1);
- return false;
- }
-
- // Record counts before swapping to caller.
- UMA_HISTOGRAM_COUNTS("SB2.AddPrefixes", add_prefixes.size());
- UMA_HISTOGRAM_COUNTS("SB2.SubPrefixes", sub_prefixes.size());
-
- add_prefixes_result->swap(add_prefixes);
- add_full_hashes_result->swap(add_full_hashes);
-
- return true;
-}
-
-bool SafeBrowsingStoreSqlite::FinishUpdate(
- const std::vector<SBAddFullHash>& pending_adds,
- const std::set<SBPrefix>& prefix_misses,
- std::vector<SBAddPrefix>* add_prefixes_result,
- std::vector<SBAddFullHash>* add_full_hashes_result) {
- bool ret = DoUpdate(pending_adds,
- add_prefixes_result, add_full_hashes_result);
-
- // Make sure everything is closed even if DoUpdate() fails.
- if (!Close())
- return false;
-
- return ret;
-}
-
-bool SafeBrowsingStoreSqlite::CancelUpdate() {
- return Close();
-}
-
-void SafeBrowsingStoreSqlite::SetAddChunk(int32 chunk_id) {
- add_chunks_cache_.insert(chunk_id);
-}
-
-bool SafeBrowsingStoreSqlite::CheckAddChunk(int32 chunk_id) {
- return add_chunks_cache_.count(chunk_id) > 0;
-}
-
-void SafeBrowsingStoreSqlite::GetAddChunks(std::vector<int32>* out) {
- out->clear();
- out->insert(out->end(), add_chunks_cache_.begin(), add_chunks_cache_.end());
-}
-
-void SafeBrowsingStoreSqlite::SetSubChunk(int32 chunk_id) {
- sub_chunks_cache_.insert(chunk_id);
-}
-
-bool SafeBrowsingStoreSqlite::CheckSubChunk(int32 chunk_id) {
- return sub_chunks_cache_.count(chunk_id) > 0;
-}
-
-void SafeBrowsingStoreSqlite::GetSubChunks(std::vector<int32>* out) {
- out->clear();
- out->insert(out->end(), sub_chunks_cache_.begin(), sub_chunks_cache_.end());
-}
-
-void SafeBrowsingStoreSqlite::DeleteAddChunk(int32 chunk_id) {
- add_del_cache_.insert(chunk_id);
-}
-
-void SafeBrowsingStoreSqlite::DeleteSubChunk(int32 chunk_id) {
- sub_del_cache_.insert(chunk_id);
-}
-
-// static
-const FilePath SafeBrowsingStoreSqlite::JournalFileForFilename(
- const FilePath& filename) {
- return FilePath(filename.value() + FILE_PATH_LITERAL("-journal"));
-}
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_sqlite.h b/chrome/browser/safe_browsing/safe_browsing_store_sqlite.h
deleted file mode 100644
index f9d4381..0000000
--- a/chrome/browser/safe_browsing/safe_browsing_store_sqlite.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_STORE_SQLITE_H_
-#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_STORE_SQLITE_H_
-#pragma once
-
-#include <set>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/file_path.h"
-#include "base/scoped_ptr.h"
-#include "chrome/browser/safe_browsing/safe_browsing_store.h"
-#include "testing/gtest/include/gtest/gtest_prod.h"
-
-struct sqlite3;
-class SqliteStatementCache;
-class SQLTransaction;
-
-class SafeBrowsingStoreSqlite : public SafeBrowsingStore {
- public:
- SafeBrowsingStoreSqlite();
- virtual ~SafeBrowsingStoreSqlite();
-
- virtual bool Delete();
-
- virtual void Init(const FilePath& filename,
- Callback0::Type* corruption_callback);
-
- virtual bool BeginChunk();
-
- // Get all Add prefixes out from the store.
- virtual bool GetAddPrefixes(std::vector<SBAddPrefix>* add_prefixes);
- virtual bool WriteAddPrefix(int32 chunk_id, SBPrefix prefix);
- virtual bool WriteAddHash(int32 chunk_id,
- base::Time receive_time,
- const SBFullHash& full_hash);
- virtual bool WriteSubPrefix(int32 chunk_id,
- int32 add_chunk_id, SBPrefix prefix);
- virtual bool WriteSubHash(int32 chunk_id, int32 add_chunk_id,
- const SBFullHash& full_hash);
- virtual bool FinishChunk();
-
- virtual bool BeginUpdate();
- // TODO(shess): Should not be public.
- virtual bool DoUpdate(const std::vector<SBAddFullHash>& pending_adds,
- std::vector<SBAddPrefix>* add_prefixes_result,
- std::vector<SBAddFullHash>* add_full_hashes_result);
- // NOTE: |prefix_misses| is ignored, as it will be handled in
- // |SafeBrowsingStoreFile::DoUpdate()|.
- virtual bool FinishUpdate(const std::vector<SBAddFullHash>& pending_adds,
- const std::set<SBPrefix>& prefix_misses,
- std::vector<SBAddPrefix>* add_prefixes_result,
- std::vector<SBAddFullHash>* add_full_hashes_result);
- virtual bool CancelUpdate();
-
- virtual void SetAddChunk(int32 chunk_id);
- virtual bool CheckAddChunk(int32 chunk_id);
- virtual void GetAddChunks(std::vector<int32>* out);
-
- virtual void SetSubChunk(int32 chunk_id);
- virtual bool CheckSubChunk(int32 chunk_id);
- virtual void GetSubChunks(std::vector<int32>* out);
-
- virtual void DeleteAddChunk(int32 chunk_id);
- virtual void DeleteSubChunk(int32 chunk_id);
-
- // Returns the name of the SQLite journal file for |filename|.
- // Exported for unit tests.
- static const FilePath JournalFileForFilename(const FilePath& filename);
-
- private:
- // For on-the-fly migration.
- // TODO(shess): Remove (entire class) after migration.
- friend class SafeBrowsingStoreFile;
-
- // The following routines return true on success, or false on
- // failure. Failure is presumed to be persistent, so the caller
- // should stop trying and unwind the transaction.
- // OnCorruptDatabase() is called if SQLite returns SQLITE_CORRUPT.
-
- // Open |db_| from |filename_|, creating if necessary.
- bool Open();
-
- // Close |db_|, rolling back any in-progress transaction.
- bool Close();
-
- // Execute all statements in sql, returning true if every one of
- // them returns SQLITE_OK.
- bool ExecSql(const char* sql);
-
- bool SetupDatabase();
- bool CheckCompatibleVersion();
-
- bool CreateTables();
-
- // Clear the old safe-browsing data from the tables.
- bool ResetTables();
-
- // Read and write the chunks-seen data from |*_chunks_cache_|.
- // Chunk deletions are not accounted for.
- bool ReadAddChunks();
- bool ReadSubChunks();
- bool WriteAddChunks();
- bool WriteSubChunks();
-
- // Read the various types of data, skipping items which belong to
- // deleted chunks. New data is appended to the vectors.
- bool ReadAddPrefixes(std::vector<SBAddPrefix>* add_prefixes);
- bool ReadSubPrefixes(std::vector<SBSubPrefix>* sub_prefixes);
- bool ReadAddHashes(std::vector<SBAddFullHash>* add_hashes);
- bool ReadSubHashes(std::vector<SBSubFullHash>* sub_hashes);
-
- // Write the various types of data. The existing data is not
- // cleared.
- bool WriteAddPrefixes(const std::vector<SBAddPrefix>& add_prefixes);
- bool WriteSubPrefixes(const std::vector<SBSubPrefix>& sub_prefixes);
- bool WriteAddHashes(const std::vector<SBAddFullHash>& add_hashes);
- bool WriteSubHashes(const std::vector<SBSubFullHash>& sub_hashes);
-
- // Calls |corruption_callback_| if non-NULL, always returns false as
- // a convenience to the caller.
- bool OnCorruptDatabase();
-
- // The database path from Init().
- FilePath filename_;
-
- // Between BeginUpdate() and FinishUpdate(), this will be the SQLite
- // database connection. Otherwise NULL.
- sqlite3 *db_;
-
- // Cache of compiled statements for |db_|.
- // TODO(shess): Probably doesn't gain us much.
- scoped_ptr<SqliteStatementCache> statement_cache_;
-
- // Transaction for protecting database integrity between
- // BeginUpdate() and FinishUpdate().
- scoped_ptr<SQLTransaction> insert_transaction_;
-
- // The set of chunks which the store has seen. Elements are added
- // by SetAddChunk() and SetSubChunk(), and deleted on write for
- // chunks that have been deleted.
- std::set<int32> add_chunks_cache_;
- std::set<int32> sub_chunks_cache_;
-
- // Cache the DeletedAddChunk() and DeleteSubChunk() chunks for later
- // use in FinishUpdate().
- base::hash_set<int32> add_del_cache_;
- base::hash_set<int32> sub_del_cache_;
-
- // Called when SQLite returns SQLITE_CORRUPT.
- scoped_ptr<Callback0::Type> corruption_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(SafeBrowsingStoreSqlite);
-};
-
-#endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_STORE_SQLITE_H_
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_sqlite_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_store_sqlite_unittest.cc
deleted file mode 100644
index 8364cf2..0000000
--- a/chrome/browser/safe_browsing/safe_browsing_store_sqlite_unittest.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/safe_browsing/safe_browsing_store_sqlite.h"
-
-#include "chrome/browser/safe_browsing/safe_browsing_store_unittest_helper.h"
-#include "chrome/test/file_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-namespace {
-
-const FilePath::CharType kFolderPrefix[] =
- FILE_PATH_LITERAL("SafeBrowsingTestStoreSqlite");
-
-class SafeBrowsingStoreSqliteTest : public PlatformTest {
- public:
- virtual void SetUp() {
- PlatformTest::SetUp();
-
- FilePath temp_dir;
- ASSERT_TRUE(file_util::CreateNewTempDirectory(kFolderPrefix, &temp_dir));
-
- file_deleter_.reset(new FileAutoDeleter(temp_dir));
-
- filename_ = temp_dir;
- filename_ = filename_.AppendASCII("SafeBrowsingTestStore");
- file_util::Delete(filename_, false);
-
- const FilePath journal_file =
- SafeBrowsingStoreSqlite::JournalFileForFilename(filename_);
- file_util::Delete(journal_file, false);
-
- store_.reset(new SafeBrowsingStoreSqlite());
- store_->Init(filename_, NULL);
- }
- virtual void TearDown() {
- store_->Delete();
- store_.reset();
- file_deleter_.reset();
-
- PlatformTest::TearDown();
- }
-
- scoped_ptr<FileAutoDeleter> file_deleter_;
- FilePath filename_;
- scoped_ptr<SafeBrowsingStoreSqlite> store_;
-};
-
-TEST_STORE(SafeBrowsingStoreSqliteTest, store_.get(), filename_);
-
-} // namespace
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 0f32820..55a212b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2058,8 +2058,6 @@
'browser/safe_browsing/safe_browsing_store.h',
'browser/safe_browsing/safe_browsing_store_file.cc',
'browser/safe_browsing/safe_browsing_store_file.h',
- 'browser/safe_browsing/safe_browsing_store_sqlite.cc',
- 'browser/safe_browsing/safe_browsing_store_sqlite.h',
'browser/safe_browsing/safe_browsing_util.cc',
'browser/safe_browsing/safe_browsing_util.h',
'browser/search_engines/edit_search_engine_controller.cc',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index d09fd65..2208713 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1390,7 +1390,6 @@
'browser/safe_browsing/safe_browsing_blocking_page_unittest.cc',
'browser/safe_browsing/safe_browsing_database_unittest.cc',
'browser/safe_browsing/safe_browsing_store_file_unittest.cc',
- 'browser/safe_browsing/safe_browsing_store_sqlite_unittest.cc',
'browser/safe_browsing/safe_browsing_store_unittest.cc',
'browser/safe_browsing/safe_browsing_store_unittest_helper.cc',
'browser/safe_browsing/safe_browsing_util_unittest.cc',