summaryrefslogtreecommitdiffstats
path: root/chrome/browser/safe_browsing/safe_browsing_store_file.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/safe_browsing/safe_browsing_store_file.cc')
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_store_file.cc72
1 files changed, 63 insertions, 9 deletions
diff --git a/chrome/browser/safe_browsing/safe_browsing_store_file.cc b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
index 493e397..cc8ae87 100644
--- a/chrome/browser/safe_browsing/safe_browsing_store_file.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_store_file.cc
@@ -40,6 +40,18 @@ bool FileRewind(FILE* fp) {
return rv == 0;
}
+// Move file read pointer forward by |bytes| relative to current position.
+bool FileSkip(size_t bytes, FILE* fp) {
+ // Although fseek takes negative values, for this case, we only want
+ // to skip forward.
+ DCHECK(static_cast<long>(bytes) >= 0);
+ if (static_cast<long>(bytes) < 0)
+ return false;
+ int rv = fseek(fp, static_cast<long>(bytes), SEEK_CUR);
+ DCHECK_EQ(rv, 0);
+ return rv == 0;
+}
+
// Read an array of |nmemb| items from |fp| into |ptr|, and fold the
// input data into the checksum in |context|, if non-NULL. Return
// true on success.
@@ -169,6 +181,21 @@ bool FileHeaderSanityCheck(const FilePath& filename,
return true;
}
+// This a helper function that reads header to |header|. Returns true if the
+// magic number is correct and santiy check passes.
+bool ReadAndVerifyHeader(const FilePath& filename,
+ FILE* fp,
+ FileHeader* header,
+ MD5Context* context) {
+ if (!ReadArray(header, 1, fp, context))
+ return false;
+ if (header->magic != kFileMagic || header->version != kFileVersion)
+ return false;
+ if (!FileHeaderSanityCheck(filename, *header))
+ return false;
+ return true;
+}
+
} // namespace
// static
@@ -263,6 +290,28 @@ bool SafeBrowsingStoreFile::WriteAddPrefix(int32 chunk_id, SBPrefix prefix) {
return true;
}
+bool SafeBrowsingStoreFile::GetAddPrefixes(
+ std::vector<SBAddPrefix>* add_prefixes) {
+ add_prefixes->clear();
+
+ file_util::ScopedFILE file(file_util::OpenFile(filename_, "rb"));
+ if (file.get() == NULL) return false;
+
+ FileHeader header;
+ if (!ReadAndVerifyHeader(filename_, file.get(), &header, NULL))
+ return OnCorruptDatabase();
+
+ size_t add_prefix_offset = header.add_chunk_count * sizeof(int32) +
+ header.sub_chunk_count * sizeof(int32);
+ if (!FileSkip(add_prefix_offset, file.get()))
+ return false;
+
+ if (!ReadToVector(add_prefixes, header.add_prefix_count, file.get(), NULL))
+ return false;
+
+ return true;
+}
+
bool SafeBrowsingStoreFile::WriteAddHash(int32 chunk_id,
base::Time receive_time,
const SBFullHash& full_hash) {
@@ -437,10 +486,13 @@ bool SafeBrowsingStoreFile::FinishChunk() {
bool SafeBrowsingStoreFile::DoUpdate(
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) {
DCHECK(old_store_.get() || file_.get() || empty_);
DCHECK(new_file_.get());
+ CHECK(add_prefixes_result);
+ CHECK(add_full_hashes_result);
std::vector<SBAddPrefix> add_prefixes;
std::vector<SBSubPrefix> sub_prefixes;
@@ -470,7 +522,6 @@ bool SafeBrowsingStoreFile::DoUpdate(
if (!old_store_->CancelUpdate())
return OnCorruptDatabase();
} else if (!empty_) {
- // Read |file_| into the vectors.
DCHECK(file_.get());
if (!FileRewind(file_.get()))
@@ -481,13 +532,7 @@ bool SafeBrowsingStoreFile::DoUpdate(
// Read the file header and make sure it looks right.
FileHeader header;
- if (!ReadArray(&header, 1, file_.get(), &context))
- return OnCorruptDatabase();
-
- if (header.magic != kFileMagic || header.version != kFileVersion)
- return OnCorruptDatabase();
-
- if (!FileHeaderSanityCheck(filename_, header))
+ if (!ReadAndVerifyHeader(filename_, file_.get(), &header, &context))
return OnCorruptDatabase();
// Re-read the chunks-seen data to get to the later data in the
@@ -517,6 +562,7 @@ bool SafeBrowsingStoreFile::DoUpdate(
MD5Digest file_digest;
if (!ReadArray(&file_digest, 1, file_.get(), NULL))
return OnCorruptDatabase();
+
if (0 != memcmp(&file_digest, &calculated_digest, sizeof(file_digest)))
return OnCorruptDatabase();
@@ -577,6 +623,10 @@ bool SafeBrowsingStoreFile::DoUpdate(
add_full_hashes.insert(add_full_hashes.end(),
pending_adds.begin(), pending_adds.end());
+ // Check how often a prefix was checked which wasn't in the
+ // database.
+ SBCheckPrefixMisses(add_prefixes, prefix_misses);
+
// Knock the subs from the adds and process deleted chunks.
SBProcessSubs(&add_prefixes, &sub_prefixes,
&add_full_hashes, &sub_full_hashes,
@@ -658,9 +708,13 @@ bool SafeBrowsingStoreFile::DoUpdate(
bool SafeBrowsingStoreFile::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,
+ DCHECK(add_prefixes_result);
+ DCHECK(add_full_hashes_result);
+
+ bool ret = DoUpdate(pending_adds, prefix_misses,
add_prefixes_result, add_full_hashes_result);
if (!ret) {