Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(808)

Unified Diff: components/safe_browsing_db/v4_store.cc

Issue 2066083002: SafeBrowising: Read and write V4Store from/to disk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@01_UpdateDbAndStores
Patch Set: Nit: Make store creation and use more consistent. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/safe_browsing_db/v4_store.cc
diff --git a/components/safe_browsing_db/v4_store.cc b/components/safe_browsing_db/v4_store.cc
index 9db2ab37f10ffab0067ae231fa44f00fabdd2f5c..a486c7f630eee4327ea55903fec6fd4e70dad588 100644
--- a/components/safe_browsing_db/v4_store.cc
+++ b/components/safe_browsing_db/v4_store.cc
@@ -4,11 +4,38 @@
#include "base/base64.h"
#include "base/bind.h"
+#include "base/files/file_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
#include "base/strings/stringprintf.h"
#include "components/safe_browsing_db/v4_store.h"
+#include "components/safe_browsing_db/v4_store.pb.h"
namespace safe_browsing {
+namespace {
+const uint32_t kFileMagic = 0x600D71FE;
+
+const uint32_t kFileVersion = 9;
+
+void RecordStoreReadResult(StoreReadResult result) {
+ UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreReadResult", result,
+ STORE_READ_RESULT_MAX);
+}
+
+void RecordStoreWriteResult(StoreWriteResult result) {
+ UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.V4StoreWriteResult", result,
+ STORE_WRITE_RESULT_MAX);
+}
+
+// Returns the name of the temporary file used to buffer data for
+// |filename|. Exported for unit tests.
+const base::FilePath TemporaryFileForFilename(const base::FilePath& filename) {
+ return base::FilePath(filename.value() + FILE_PATH_LITERAL("_new"));
+}
+
+} // namespace
+
std::ostream& operator<<(std::ostream& os, const V4Store& store) {
os << store.DebugString();
return os;
@@ -17,7 +44,17 @@ std::ostream& operator<<(std::ostream& os, const V4Store& store) {
V4Store* V4StoreFactory::CreateV4Store(
const scoped_refptr<base::SequencedTaskRunner>& task_runner,
const base::FilePath& store_path) {
- return new V4Store(task_runner, store_path);
+ V4Store* new_store = new V4Store(task_runner, store_path);
+ new_store->Initialize();
+ return new_store;
+}
+
+void V4Store::Initialize() {
+ // If a state already exists, don't re-initilize.
+ DCHECK(state_.empty());
+
+ StoreReadResult store_read_result = ReadFromDisk();
+ RecordStoreReadResult(store_read_result);
}
V4Store::V4Store(const scoped_refptr<base::SequencedTaskRunner>& task_runner,
@@ -50,9 +87,94 @@ void V4Store::ApplyUpdate(
// TODO(vakh): The new store currently only picks up the new state. Do more.
new_store->state_ = response.new_client_state();
+ // TODO(vakh): Merge the old store and the new update in new_store.
+ // Then, create a ListUpdateResponse containing RICE encoded hash-prefixes and
+ // response_type as FULL_UPDATE, and write that to disk.
+ StoreWriteResult result = new_store->WriteToDisk(response);
+ RecordStoreWriteResult(result);
+
// new_store is done updating, pass it to the callback.
callback_task_runner->PostTask(
FROM_HERE, base::Bind(callback, base::Passed(&new_store)));
}
+StoreReadResult V4Store::ReadFromDisk() {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+
+ std::string contents;
+ bool read_success = base::ReadFileToString(store_path_, &contents);
+ if (!read_success) {
+ return FILE_UNREADABLE_FAILURE;
+ }
+
+ if (contents.empty()) {
+ return FILE_EMPTY_FAILURE;
+ }
+
+ V4StoreFileFormat file_format;
+ if (!file_format.ParseFromString(contents)) {
+ return PROTO_PARSING_FAILURE;
+ }
+
+ if (file_format.magic_number() != kFileMagic) {
+ DVLOG(1) << "Unexpected magic number found in file: "
+ << file_format.magic_number();
+ return UNEXPECTED_MAGIC_NUMBER_FAILURE;
+ }
+
+ UMA_HISTOGRAM_SPARSE_SLOWLY("SafeBrowsing.V4StoreVersionRead",
+ file_format.version_number());
+ if (file_format.version_number() != kFileVersion) {
+ DVLOG(1) << "File version incompatible: " << file_format.version_number()
+ << "; expected: " << kFileVersion;
+ return FILE_VERSION_INCOMPATIBLE_FAILURE;
+ }
+
+ if (!file_format.has_list_update_response()) {
+ return HASH_PREFIX_INFO_MISSING_FAILURE;
+ }
+
+ ListUpdateResponse list_update_response = file_format.list_update_response();
+ state_ = list_update_response.new_client_state();
+ // TODO(vakh): Do more with what's read from the disk.
+
+ return READ_SUCCESS;
+}
+
+StoreWriteResult V4Store::WriteToDisk(
+ const ListUpdateResponse& response) const {
+ // Do not write partial updates to the disk.
+ // After merging the updates, the ListUpdateResponse passed to this method
+ // should be a FULL_UPDATE.
+ if (!response.has_response_type() ||
+ response.response_type() != ListUpdateResponse::FULL_UPDATE) {
+ DVLOG(1) << "response.has_response_type(): "
+ << response.has_response_type();
+ DVLOG(1) << "response.response_type(): " << response.response_type();
+ return INVALID_RESPONSE_TYPE_FAILURE;
+ }
+
+ // Attempt writing to a temporary file first and at the end, swap the files.
+ const base::FilePath new_filename = TemporaryFileForFilename(store_path_);
+
+ V4StoreFileFormat file_format;
+ file_format.set_magic_number(kFileMagic);
+ file_format.set_version_number(kFileVersion);
+ ListUpdateResponse* response_to_write =
+ file_format.mutable_list_update_response();
+ *response_to_write = response;
+ std::string file_format_string;
+ file_format.SerializeToString(&file_format_string);
+ size_t written = base::WriteFile(new_filename, file_format_string.data(),
+ file_format_string.size());
+ DCHECK_EQ(file_format_string.size(), written);
+
+ if (!base::Move(new_filename, store_path_)) {
+ DVLOG(1) << "store_path_: " << store_path_.value();
+ return UNABLE_TO_RENAME_FAILURE;
+ }
+
+ return WRITE_SUCCESS;
+}
+
} // namespace safe_browsing

Powered by Google App Engine
This is Rietveld 408576698