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

Side by Side Diff: content/browser/indexed_db/indexed_db_database.cc

Issue 237143006: Make iterating over a corrupted IndexedDB fail. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added Status checks. Created 6 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_database.h" 5 #include "content/browser/indexed_db/indexed_db_database.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <set> 8 #include <set>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } 85 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; }
86 86
87 private: 87 private:
88 scoped_refptr<IndexedDBCallbacks> callbacks_; 88 scoped_refptr<IndexedDBCallbacks> callbacks_;
89 }; 89 };
90 90
91 scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( 91 scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create(
92 const base::string16& name, 92 const base::string16& name,
93 IndexedDBBackingStore* backing_store, 93 IndexedDBBackingStore* backing_store,
94 IndexedDBFactory* factory, 94 IndexedDBFactory* factory,
95 const Identifier& unique_identifier) { 95 const Identifier& unique_identifier,
96 leveldb::Status* s) {
96 scoped_refptr<IndexedDBDatabase> database = 97 scoped_refptr<IndexedDBDatabase> database =
97 new IndexedDBDatabase(name, backing_store, factory, unique_identifier); 98 new IndexedDBDatabase(name, backing_store, factory, unique_identifier);
98 if (!database->OpenInternal().ok()) 99 *s = database->OpenInternal();
99 return 0; 100 if (s->ok())
100 return database; 101 return database;
102 else
103 return NULL;
101 } 104 }
102 105
103 namespace { 106 namespace {
104 const base::string16::value_type kNoStringVersion[] = {0}; 107 const base::string16::value_type kNoStringVersion[] = {0};
105 } 108 }
106 109
107 IndexedDBDatabase::IndexedDBDatabase(const base::string16& name, 110 IndexedDBDatabase::IndexedDBDatabase(const base::string16& name,
108 IndexedDBBackingStore* backing_store, 111 IndexedDBBackingStore* backing_store,
109 IndexedDBFactory* factory, 112 IndexedDBFactory* factory,
110 const Identifier& unique_identifier) 113 const Identifier& unique_identifier)
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 IndexedDBTransaction* transaction) { 523 IndexedDBTransaction* transaction) {
521 IDB_TRACE("IndexedDBDatabase::GetOperation"); 524 IDB_TRACE("IndexedDBDatabase::GetOperation");
522 525
523 DCHECK(metadata_.object_stores.find(object_store_id) != 526 DCHECK(metadata_.object_stores.find(object_store_id) !=
524 metadata_.object_stores.end()); 527 metadata_.object_stores.end());
525 const IndexedDBObjectStoreMetadata& object_store_metadata = 528 const IndexedDBObjectStoreMetadata& object_store_metadata =
526 metadata_.object_stores[object_store_id]; 529 metadata_.object_stores[object_store_id];
527 530
528 const IndexedDBKey* key; 531 const IndexedDBKey* key;
529 532
533 leveldb::Status s;
530 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 534 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
531 if (key_range->IsOnlyKey()) { 535 if (key_range->IsOnlyKey()) {
532 key = &key_range->lower(); 536 key = &key_range->lower();
533 } else { 537 } else {
534 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 538 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
535 DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY); 539 DCHECK_NE(cursor_type, indexed_db::CURSOR_KEY_ONLY);
536 // ObjectStore Retrieval Operation 540 // ObjectStore Retrieval Operation
537 backing_store_cursor = backing_store_->OpenObjectStoreCursor( 541 backing_store_cursor = backing_store_->OpenObjectStoreCursor(
538 transaction->BackingStoreTransaction(), 542 transaction->BackingStoreTransaction(),
539 id(), 543 id(),
540 object_store_id, 544 object_store_id,
541 *key_range, 545 *key_range,
542 indexed_db::CURSOR_NEXT); 546 indexed_db::CURSOR_NEXT,
547 &s);
543 } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 548 } else if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
544 // Index Value Retrieval Operation 549 // Index Value Retrieval Operation
545 backing_store_cursor = backing_store_->OpenIndexKeyCursor( 550 backing_store_cursor = backing_store_->OpenIndexKeyCursor(
546 transaction->BackingStoreTransaction(), 551 transaction->BackingStoreTransaction(),
547 id(), 552 id(),
548 object_store_id, 553 object_store_id,
549 index_id, 554 index_id,
550 *key_range, 555 *key_range,
551 indexed_db::CURSOR_NEXT); 556 indexed_db::CURSOR_NEXT,
557 &s);
552 } else { 558 } else {
553 // Index Referenced Value Retrieval Operation 559 // Index Referenced Value Retrieval Operation
554 backing_store_cursor = backing_store_->OpenIndexCursor( 560 backing_store_cursor = backing_store_->OpenIndexCursor(
555 transaction->BackingStoreTransaction(), 561 transaction->BackingStoreTransaction(),
556 id(), 562 id(),
557 object_store_id, 563 object_store_id,
558 index_id, 564 index_id,
559 *key_range, 565 *key_range,
560 indexed_db::CURSOR_NEXT); 566 indexed_db::CURSOR_NEXT,
567 &s);
568 }
569
570 if (!s.ok()) {
571 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
572 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
573 "Internal error deleting data in range");
574 if (s.IsCorruption()) {
575 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
576 error);
577 }
561 } 578 }
562 579
563 if (!backing_store_cursor) { 580 if (!backing_store_cursor) {
564 callbacks->OnSuccess(); 581 callbacks->OnSuccess();
565 return; 582 return;
566 } 583 }
567 584
568 key = &backing_store_cursor->key(); 585 key = &backing_store_cursor->key();
569 } 586 }
570 587
571 scoped_ptr<IndexedDBKey> primary_key; 588 scoped_ptr<IndexedDBKey> primary_key;
572 leveldb::Status s;
573 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 589 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
574 // Object Store Retrieval Operation 590 // Object Store Retrieval Operation
575 IndexedDBValue value; 591 IndexedDBValue value;
576 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 592 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
577 id(), 593 id(),
578 object_store_id, 594 object_store_id,
579 *key, 595 *key,
580 &value); 596 &value);
581 if (!s.ok()) { 597 if (!s.ok()) {
582 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 598 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 IndexedDBTransaction* transaction) { 1039 IndexedDBTransaction* transaction) {
1024 IDB_TRACE("IndexedDBDatabase::OpenCursorOperation"); 1040 IDB_TRACE("IndexedDBDatabase::OpenCursorOperation");
1025 1041
1026 // The frontend has begun indexing, so this pauses the transaction 1042 // The frontend has begun indexing, so this pauses the transaction
1027 // until the indexing is complete. This can't happen any earlier 1043 // until the indexing is complete. This can't happen any earlier
1028 // because we don't want to switch to early mode in case multiple 1044 // because we don't want to switch to early mode in case multiple
1029 // indexes are being created in a row, with Put()'s in between. 1045 // indexes are being created in a row, with Put()'s in between.
1030 if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK) 1046 if (params->task_type == IndexedDBDatabase::PREEMPTIVE_TASK)
1031 transaction->AddPreemptiveEvent(); 1047 transaction->AddPreemptiveEvent();
1032 1048
1049 leveldb::Status s;
1033 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1050 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
1034 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) { 1051 if (params->index_id == IndexedDBIndexMetadata::kInvalidId) {
1035 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1052 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1036 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 1053 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK);
1037 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1054 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
1038 transaction->BackingStoreTransaction(), 1055 transaction->BackingStoreTransaction(),
1039 id(), 1056 id(),
1040 params->object_store_id, 1057 params->object_store_id,
1041 *params->key_range, 1058 *params->key_range,
1042 params->direction); 1059 params->direction,
1060 &s);
1043 } else { 1061 } else {
1044 backing_store_cursor = backing_store_->OpenObjectStoreCursor( 1062 backing_store_cursor = backing_store_->OpenObjectStoreCursor(
1045 transaction->BackingStoreTransaction(), 1063 transaction->BackingStoreTransaction(),
1046 id(), 1064 id(),
1047 params->object_store_id, 1065 params->object_store_id,
1048 *params->key_range, 1066 *params->key_range,
1049 params->direction); 1067 params->direction,
1068 &s);
1050 } 1069 }
1051 } else { 1070 } else {
1052 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK); 1071 DCHECK_EQ(params->task_type, IndexedDBDatabase::NORMAL_TASK);
1053 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1072 if (params->cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1054 backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1073 backing_store_cursor = backing_store_->OpenIndexKeyCursor(
1055 transaction->BackingStoreTransaction(), 1074 transaction->BackingStoreTransaction(),
1056 id(), 1075 id(),
1057 params->object_store_id, 1076 params->object_store_id,
1058 params->index_id, 1077 params->index_id,
1059 *params->key_range, 1078 *params->key_range,
1060 params->direction); 1079 params->direction,
1080 &s);
1061 } else { 1081 } else {
1062 backing_store_cursor = backing_store_->OpenIndexCursor( 1082 backing_store_cursor = backing_store_->OpenIndexCursor(
1063 transaction->BackingStoreTransaction(), 1083 transaction->BackingStoreTransaction(),
1064 id(), 1084 id(),
1065 params->object_store_id, 1085 params->object_store_id,
1066 params->index_id, 1086 params->index_id,
1067 *params->key_range, 1087 *params->key_range,
1068 params->direction); 1088 params->direction,
1089 &s);
1090 }
1091 }
1092
1093 if (!s.ok()) {
1094 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1095 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1096 "Internal error opening cursor operation");
1097 if (s.IsCorruption()) {
1098 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
1099 error);
1069 } 1100 }
1070 } 1101 }
1071 1102
1072 if (!backing_store_cursor) { 1103 if (!backing_store_cursor) {
1104 // Why is Success being called?
1073 params->callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL)); 1105 params->callbacks->OnSuccess(static_cast<IndexedDBValue*>(NULL));
1074 return; 1106 return;
1075 } 1107 }
1076 1108
1077 scoped_refptr<IndexedDBCursor> cursor = 1109 scoped_refptr<IndexedDBCursor> cursor =
1078 new IndexedDBCursor(backing_store_cursor.Pass(), 1110 new IndexedDBCursor(backing_store_cursor.Pass(),
1079 params->cursor_type, 1111 params->cursor_type,
1080 params->task_type, 1112 params->task_type,
1081 transaction); 1113 transaction);
1082 params->callbacks->OnSuccess( 1114 params->callbacks->OnSuccess(
(...skipping 24 matching lines...) Expand all
1107 void IndexedDBDatabase::CountOperation( 1139 void IndexedDBDatabase::CountOperation(
1108 int64 object_store_id, 1140 int64 object_store_id,
1109 int64 index_id, 1141 int64 index_id,
1110 scoped_ptr<IndexedDBKeyRange> key_range, 1142 scoped_ptr<IndexedDBKeyRange> key_range,
1111 scoped_refptr<IndexedDBCallbacks> callbacks, 1143 scoped_refptr<IndexedDBCallbacks> callbacks,
1112 IndexedDBTransaction* transaction) { 1144 IndexedDBTransaction* transaction) {
1113 IDB_TRACE("IndexedDBDatabase::CountOperation"); 1145 IDB_TRACE("IndexedDBDatabase::CountOperation");
1114 uint32 count = 0; 1146 uint32 count = 0;
1115 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor; 1147 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor;
1116 1148
1149 leveldb::Status s;
1117 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 1150 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1118 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor( 1151 backing_store_cursor = backing_store_->OpenObjectStoreKeyCursor(
1119 transaction->BackingStoreTransaction(), 1152 transaction->BackingStoreTransaction(),
1120 id(), 1153 id(),
1121 object_store_id, 1154 object_store_id,
1122 *key_range, 1155 *key_range,
1123 indexed_db::CURSOR_NEXT); 1156 indexed_db::CURSOR_NEXT,
1157 &s);
1124 } else { 1158 } else {
1125 backing_store_cursor = backing_store_->OpenIndexKeyCursor( 1159 backing_store_cursor = backing_store_->OpenIndexKeyCursor(
1126 transaction->BackingStoreTransaction(), 1160 transaction->BackingStoreTransaction(),
1127 id(), 1161 id(),
1128 object_store_id, 1162 object_store_id,
1129 index_id, 1163 index_id,
1130 *key_range, 1164 *key_range,
1131 indexed_db::CURSOR_NEXT); 1165 indexed_db::CURSOR_NEXT,
1166 &s);
1167 }
1168 if (!s.ok()) {
1169 DLOG(ERROR) << "Unable perform count operation: " << s.ToString();
1170 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1171 "Internal error performing count operation");
1172 if (s.IsCorruption()) {
1173 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
1174 error);
1175 }
1132 } 1176 }
1133 if (!backing_store_cursor) { 1177 if (!backing_store_cursor) {
1134 callbacks->OnSuccess(count); 1178 callbacks->OnSuccess(count);
1135 return; 1179 return;
1136 } 1180 }
1137 1181
1138 do { 1182 do {
1139 ++count; 1183 ++count;
1140 } while (backing_store_cursor->Continue()); 1184 } while (backing_store_cursor->Continue(&s));
1185
1186 // TODO(cmumford): Check for database corruption.
1141 1187
1142 callbacks->OnSuccess(count); 1188 callbacks->OnSuccess(count);
1143 } 1189 }
1144 1190
1145 void IndexedDBDatabase::DeleteRange( 1191 void IndexedDBDatabase::DeleteRange(
1146 int64 transaction_id, 1192 int64 transaction_id,
1147 int64 object_store_id, 1193 int64 object_store_id,
1148 scoped_ptr<IndexedDBKeyRange> key_range, 1194 scoped_ptr<IndexedDBKeyRange> key_range,
1149 scoped_refptr<IndexedDBCallbacks> callbacks) { 1195 scoped_refptr<IndexedDBCallbacks> callbacks) {
1150 IDB_TRACE("IndexedDBDatabase::DeleteRange"); 1196 IDB_TRACE("IndexedDBDatabase::DeleteRange");
(...skipping 11 matching lines...) Expand all
1162 base::Passed(&key_range), 1208 base::Passed(&key_range),
1163 callbacks)); 1209 callbacks));
1164 } 1210 }
1165 1211
1166 void IndexedDBDatabase::DeleteRangeOperation( 1212 void IndexedDBDatabase::DeleteRangeOperation(
1167 int64 object_store_id, 1213 int64 object_store_id,
1168 scoped_ptr<IndexedDBKeyRange> key_range, 1214 scoped_ptr<IndexedDBKeyRange> key_range,
1169 scoped_refptr<IndexedDBCallbacks> callbacks, 1215 scoped_refptr<IndexedDBCallbacks> callbacks,
1170 IndexedDBTransaction* transaction) { 1216 IndexedDBTransaction* transaction) {
1171 IDB_TRACE("IndexedDBDatabase::DeleteRangeOperation"); 1217 IDB_TRACE("IndexedDBDatabase::DeleteRangeOperation");
1218 leveldb::Status s;
1172 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor = 1219 scoped_ptr<IndexedDBBackingStore::Cursor> backing_store_cursor =
1173 backing_store_->OpenObjectStoreCursor( 1220 backing_store_->OpenObjectStoreCursor(
1174 transaction->BackingStoreTransaction(), 1221 transaction->BackingStoreTransaction(),
1175 id(), 1222 id(),
1176 object_store_id, 1223 object_store_id,
1177 *key_range, 1224 *key_range,
1178 indexed_db::CURSOR_NEXT); 1225 indexed_db::CURSOR_NEXT,
1179 if (backing_store_cursor) { 1226 &s);
1227 if (backing_store_cursor && s.ok()) {
1180 do { 1228 do {
1181 if (!backing_store_->DeleteRecord( 1229 if (!backing_store_->DeleteRecord(
1182 transaction->BackingStoreTransaction(), 1230 transaction->BackingStoreTransaction(),
1183 id(), 1231 id(),
1184 object_store_id, 1232 object_store_id,
1185 backing_store_cursor->record_identifier()) 1233 backing_store_cursor->record_identifier())
1186 .ok()) { 1234 .ok()) {
1187 callbacks->OnError( 1235 callbacks->OnError(
1188 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, 1236 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
1189 "Internal error deleting data in range")); 1237 "Internal error deleting data in range"));
1190 return; 1238 return;
1191 } 1239 }
1192 } while (backing_store_cursor->Continue()); 1240 } while (backing_store_cursor->Continue(&s));
1241 }
1242
1243 if (!s.ok()) {
1244 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1245 ASCIIToUTF16("Internal error deleting range"));
1246 transaction->Abort(error);
1247 if (s.IsCorruption()) {
1248 factory_->HandleBackingStoreCorruption(backing_store_->origin_url(),
1249 error);
1250 }
1251 return;
1193 } 1252 }
1194 1253
1195 callbacks->OnSuccess(); 1254 callbacks->OnSuccess();
1196 } 1255 }
1197 1256
1198 void IndexedDBDatabase::Clear(int64 transaction_id, 1257 void IndexedDBDatabase::Clear(int64 transaction_id,
1199 int64 object_store_id, 1258 int64 object_store_id,
1200 scoped_refptr<IndexedDBCallbacks> callbacks) { 1259 scoped_refptr<IndexedDBCallbacks> callbacks) {
1201 IDB_TRACE("IndexedDBDatabase::Clear"); 1260 IDB_TRACE("IndexedDBDatabase::Clear");
1202 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1261 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 const base::string16& previous_version, 1751 const base::string16& previous_version,
1693 int64 previous_int_version, 1752 int64 previous_int_version,
1694 IndexedDBTransaction* transaction) { 1753 IndexedDBTransaction* transaction) {
1695 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1754 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
1696 DCHECK(!transaction); 1755 DCHECK(!transaction);
1697 metadata_.version = previous_version; 1756 metadata_.version = previous_version;
1698 metadata_.int_version = previous_int_version; 1757 metadata_.int_version = previous_int_version;
1699 } 1758 }
1700 1759
1701 } // namespace content 1760 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698