| 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 3c5aa2d9537b13b0a734d8ca98ec963d2f55ac60..64e15457774ea87de1cf32ff808660ff7c85a7ea 100644
|
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc
|
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
|
| @@ -602,6 +602,8 @@ IndexedDBBackingStore::~IndexedDBBackingStore() {
|
| policy->RevokeAllPermissionsForFile(*iter, blob_path_);
|
| }
|
| }
|
| + STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(),
|
| + incognito_blob_map_.end());
|
| // db_'s destructor uses comparator_. The order of destruction is important.
|
| db_.reset();
|
| comparator_.reset();
|
| @@ -1016,7 +1018,8 @@ std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames(
|
| *s = it->Next()) {
|
| StringPiece slice(it->Key());
|
| DatabaseNameKey database_name_key;
|
| - if (!DatabaseNameKey::Decode(&slice, &database_name_key)) {
|
| + if (!DatabaseNameKey::Decode(&slice, &database_name_key) ||
|
| + !slice.empty()) {
|
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
|
| continue;
|
| }
|
| @@ -1256,9 +1259,10 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores(
|
| while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
|
| StringPiece slice(it->Key());
|
| ObjectStoreMetaDataKey meta_data_key;
|
| - bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key);
|
| + bool ok =
|
| + ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key) && slice.empty();
|
| DCHECK(ok);
|
| - if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) {
|
| + if (!ok || meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) {
|
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
|
| // Possible stale metadata, but don't fail the load.
|
| s = it->Next();
|
| @@ -1764,7 +1768,7 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
|
| s = it->Next()) {
|
| StringPiece slice(it->Key());
|
| ObjectStoreDataKey data_key;
|
| - if (!ObjectStoreDataKey::Decode(&slice, &data_key)) {
|
| + if (!ObjectStoreDataKey::Decode(&slice, &data_key) || !slice.empty()) {
|
| INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
|
| return InternalInconsistencyStatus();
|
| }
|
| @@ -3398,17 +3402,28 @@ IndexedDBBackingStore::OpenIndexCursor(
|
|
|
| IndexedDBBackingStore::Transaction::Transaction(
|
| IndexedDBBackingStore* backing_store)
|
| - : backing_store_(backing_store), database_id_(-1) {}
|
| + : backing_store_(backing_store), database_id_(-1) {
|
| +}
|
|
|
| IndexedDBBackingStore::Transaction::~Transaction() {
|
| STLDeleteContainerPairSecondPointers(
|
| blob_change_map_.begin(), blob_change_map_.end());
|
| + STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(),
|
| + incognito_blob_map_.end());
|
| }
|
|
|
| void IndexedDBBackingStore::Transaction::Begin() {
|
| IDB_TRACE("IndexedDBBackingStore::Transaction::Begin");
|
| DCHECK(!transaction_.get());
|
| transaction_ = new LevelDBTransaction(backing_store_->db_.get());
|
| +
|
| + // If incognito, this snapshots blobs just as the above transaction_
|
| + // constructor snapshots the leveldb.
|
| + BlobChangeMap::const_iterator iter;
|
| + for (iter = backing_store_->incognito_blob_map_.begin();
|
| + iter != backing_store_->incognito_blob_map_.end();
|
| + ++iter)
|
| + incognito_blob_map_[iter->first] = iter->second->Clone().release();
|
| }
|
|
|
| leveldb::Status IndexedDBBackingStore::Transaction::Commit() {
|
| @@ -3416,6 +3431,23 @@ leveldb::Status IndexedDBBackingStore::Transaction::Commit() {
|
| DCHECK(transaction_.get());
|
| leveldb::Status s = transaction_->Commit();
|
| transaction_ = NULL;
|
| +
|
| + if (s.ok() && backing_store_->is_incognito() && !blob_change_map_.empty()) {
|
| + BlobChangeMap& target_map = backing_store_->incognito_blob_map_;
|
| + BlobChangeMap::iterator iter;
|
| + for (iter = blob_change_map_.begin(); iter != blob_change_map_.end();
|
| + ++iter) {
|
| + BlobChangeMap::iterator target_record = target_map.find(iter->first);
|
| + if (target_record != target_map.end()) {
|
| + delete target_record->second;
|
| + target_map.erase(target_record);
|
| + }
|
| + if (iter->second) {
|
| + target_map[iter->first] = iter->second;
|
| + iter->second = NULL;
|
| + }
|
| + }
|
| + }
|
| if (!s.ok())
|
| INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
|
| return s;
|
| @@ -3478,28 +3510,41 @@ void IndexedDBBackingStore::Transaction::Rollback() {
|
| transaction_ = NULL;
|
| }
|
|
|
| -IndexedDBBackingStore::Transaction::BlobChangeRecord::BlobChangeRecord(
|
| - const std::string& key, int64 object_store_id)
|
| +IndexedDBBackingStore::BlobChangeRecord::BlobChangeRecord(
|
| + const std::string& key,
|
| + int64 object_store_id)
|
| : key_(key), object_store_id_(object_store_id) {
|
| }
|
|
|
| -IndexedDBBackingStore::Transaction::BlobChangeRecord::~BlobChangeRecord() {
|
| +IndexedDBBackingStore::BlobChangeRecord::~BlobChangeRecord() {
|
| }
|
|
|
| -void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetBlobInfo(
|
| +void IndexedDBBackingStore::BlobChangeRecord::SetBlobInfo(
|
| std::vector<IndexedDBBlobInfo>* blob_info) {
|
| blob_info_.clear();
|
| if (blob_info)
|
| blob_info_.swap(*blob_info);
|
| }
|
|
|
| -void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetHandles(
|
| +void IndexedDBBackingStore::BlobChangeRecord::SetHandles(
|
| ScopedVector<webkit_blob::BlobDataHandle>* handles) {
|
| handles_.clear();
|
| if (handles)
|
| handles_.swap(*handles);
|
| }
|
|
|
| +scoped_ptr<IndexedDBBackingStore::BlobChangeRecord>
|
| +IndexedDBBackingStore::BlobChangeRecord::Clone() const {
|
| + scoped_ptr<IndexedDBBackingStore::BlobChangeRecord> record(
|
| + new BlobChangeRecord(key_, object_store_id_));
|
| + record->blob_info_ = blob_info_;
|
| +
|
| + ScopedVector<webkit_blob::BlobDataHandle>::const_iterator iter;
|
| + for (iter = handles_.begin(); iter != handles_.end(); ++iter)
|
| + record->handles_.push_back(new webkit_blob::BlobDataHandle(**iter));
|
| + return record.Pass();
|
| +}
|
| +
|
| // This is storing an info, even if empty, even if the previous key had no blob
|
| // info that we know of. It duplicates a bunch of information stored in the
|
| // leveldb transaction, but only w.r.t. the user keys altered--we don't keep the
|
| @@ -3507,19 +3552,19 @@ void IndexedDBBackingStore::Transaction::BlobChangeRecord::SetHandles(
|
| void IndexedDBBackingStore::Transaction::PutBlobInfo(
|
| int64 database_id,
|
| int64 object_store_id,
|
| - const std::string& key,
|
| + const std::string& object_store_data_key,
|
| std::vector<IndexedDBBlobInfo>* blob_info,
|
| ScopedVector<webkit_blob::BlobDataHandle>* handles) {
|
| - DCHECK_GT(key.size(), 0UL);
|
| + DCHECK_GT(object_store_data_key.size(), 0UL);
|
| if (database_id_ < 0)
|
| database_id_ = database_id;
|
| DCHECK_EQ(database_id_, database_id);
|
|
|
| - BlobChangeMap::iterator it = blob_change_map_.find(key);
|
| + BlobChangeMap::iterator it = blob_change_map_.find(object_store_data_key);
|
| BlobChangeRecord* record = NULL;
|
| if (it == blob_change_map_.end()) {
|
| - record = new BlobChangeRecord(key, object_store_id);
|
| - blob_change_map_[key] = record;
|
| + record = new BlobChangeRecord(object_store_data_key, object_store_id);
|
| + blob_change_map_[object_store_data_key] = record;
|
| } else {
|
| record = it->second;
|
| }
|
|
|