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

Unified Diff: content/browser/indexed_db/indexed_db_backing_store.cc

Issue 333533002: Check File snapshots and Blob byte counts when writing to IDB (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Build fix Created 6 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: content/browser/indexed_db/indexed_db_backing_store.cc
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index f19e2e8f9949cca126ea2532a3c5d7100ea2d222..0a83a914f84de9848c8354a09911a9ae64ea6edd 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -2160,17 +2160,18 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
WriteDescriptorVec;
ChainedBlobWriterImpl(
int64 database_id,
- IndexedDBBackingStore* backingStore,
+ IndexedDBBackingStore* backing_store,
WriteDescriptorVec& blobs,
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback)
: waiting_for_callback_(false),
database_id_(database_id),
- backing_store_(backingStore),
+ backing_store_(backing_store),
callback_(callback),
aborted_(false) {
blobs_.swap(blobs);
iter_ = blobs_.begin();
- WriteNextFile();
+ backing_store->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&ChainedBlobWriterImpl::WriteNextFile, this));
}
virtual void set_delegate(scoped_ptr<FileWriterDelegate> delegate) OVERRIDE {
@@ -2179,7 +2180,6 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
virtual void ReportWriteCompletion(bool succeeded,
int64 bytes_written) OVERRIDE {
- // TODO(ericu): Check bytes_written against the blob's snapshot value.
DCHECK(waiting_for_callback_);
DCHECK(!succeeded || bytes_written >= 0);
waiting_for_callback_ = false;
@@ -2190,10 +2190,14 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
self_ref_ = NULL;
return;
}
- if (succeeded)
+ if (iter_->size() != -1 && iter_->size() != bytes_written)
+ succeeded = false;
+ if (succeeded) {
+ ++iter_;
WriteNextFile();
- else
+ } else {
callback_->Run(false);
+ }
}
virtual void Abort() OVERRIDE {
@@ -2219,7 +2223,6 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl
return;
}
waiting_for_callback_ = true;
- ++iter_;
}
}
@@ -2244,17 +2247,17 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
base::TaskRunner* task_runner)
: chained_blob_writer_(chained_blob_writer),
task_runner_(task_runner),
- bytes_written_(-1) {}
+ bytes_written_(0) {}
void Run(base::File::Error rv,
int64 bytes,
FileWriterDelegate::WriteProgressStatus write_status) {
+ DCHECK_GE(bytes, 0);
+ bytes_written_ += bytes;
if (write_status == FileWriterDelegate::SUCCESS_IO_PENDING)
return; // We don't care about progress events.
if (rv == base::File::FILE_OK) {
- DCHECK_GE(bytes, 0);
DCHECK_EQ(write_status, FileWriterDelegate::SUCCESS_COMPLETED);
- bytes_written_ = bytes;
} else {
DCHECK(write_status == FileWriterDelegate::ERROR_WRITE_STARTED ||
write_status == FileWriterDelegate::ERROR_WRITE_NOT_STARTED);
@@ -2320,8 +2323,15 @@ bool IndexedDBBackingStore::WriteBlobFile(
base::File::Info info;
if (base::GetFileInfo(descriptor.file_path(), &info)) {
- // TODO(ericu): Validate the snapshot date here. Expand WriteDescriptor
- // to include snapshot date and file size, and check both.
+ if (descriptor.size() != -1) {
+ if (descriptor.size() != info.size)
+ return false;
+ // The round-trip can be lossy; round to nearest millisecond.
jsbell 2014/06/18 23:26:10 This is because we've asked the filesystem for the
ericu 2014/06/18 23:28:44 I believe that's the case. I've hit this before i
+ int64 delta = (descriptor.last_modified() -
+ info.last_modified).InMilliseconds();
+ if (std::abs(delta) > 1)
+ return false;
+ }
if (!base::TouchFile(path, info.last_accessed, info.last_modified)) {
// TODO(ericu): Complain quietly; timestamp's probably not vital.
}
@@ -3876,10 +3886,15 @@ leveldb::Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction(
journal.push_back(journal_entry);
if (info_iter->is_file()) {
new_files_to_write->push_back(
- WriteDescriptor(info_iter->file_path(), next_blob_key));
+ WriteDescriptor(info_iter->file_path(),
+ next_blob_key,
+ info_iter->size(),
+ info_iter->last_modified()));
} else {
- new_files_to_write->push_back(WriteDescriptor(
- getURLFromUUID(info_iter->uuid()), next_blob_key));
+ new_files_to_write->push_back(
+ WriteDescriptor(getURLFromUUID(info_iter->uuid()),
+ next_blob_key,
+ info_iter->size()));
}
info_iter->set_key(next_blob_key);
new_blob_keys.push_back(&*info_iter);
@@ -4066,7 +4081,8 @@ class IndexedDBBackingStore::Transaction::BlobWriteCallbackWrapper
: transaction_(transaction), callback_(callback) {}
virtual void Run(bool succeeded) OVERRIDE {
callback_->Run(succeeded);
- transaction_->chained_blob_writer_ = NULL;
+ if (succeeded) // Else it's already been deleted during rollback.
+ transaction_->chained_blob_writer_ = NULL;
}
private:
@@ -4213,12 +4229,21 @@ void IndexedDBBackingStore::Transaction::PutBlobInfo(
IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
const GURL& url,
- int64_t key)
- : is_file_(false), url_(url), key_(key) {}
+ int64_t key,
+ int64_t size)
+ : is_file_(false), url_(url), key_(key), size_(size) {
+}
IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
const FilePath& file_path,
- int64_t key)
- : is_file_(true), file_path_(file_path), key_(key) {}
+ int64_t key,
+ int64_t size,
+ base::Time last_modified)
+ : is_file_(true),
+ file_path_(file_path),
+ key_(key),
+ size_(size),
+ last_modified_(last_modified) {
+}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698