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

Side by Side Diff: content/browser/indexed_db/leveldb/leveldb_transaction.cc

Issue 237143006: Make iterating over a corrupted IndexedDB fail. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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/leveldb/leveldb_transaction.h" 5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 8 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" 9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h"
10 #include "third_party/leveldatabase/src/include/leveldb/db.h" 10 #include "third_party/leveldatabase/src/include/leveldb/db.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 123
124 scoped_ptr<LevelDBTransaction::DataIterator> 124 scoped_ptr<LevelDBTransaction::DataIterator>
125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { 125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) {
126 return make_scoped_ptr(new DataIterator(transaction)); 126 return make_scoped_ptr(new DataIterator(transaction));
127 } 127 }
128 128
129 bool LevelDBTransaction::DataIterator::IsValid() const { 129 bool LevelDBTransaction::DataIterator::IsValid() const {
130 return iterator_ != data_->end(); 130 return iterator_ != data_->end();
131 } 131 }
132 132
133 void LevelDBTransaction::DataIterator::SeekToLast() { 133 leveldb::Status LevelDBTransaction::DataIterator::SeekToLast() {
134 iterator_ = data_->end(); 134 iterator_ = data_->end();
135 if (iterator_ != data_->begin()) 135 if (iterator_ != data_->begin())
136 --iterator_; 136 --iterator_;
137 return leveldb::Status::OK();
137 } 138 }
138 139
139 void LevelDBTransaction::DataIterator::Seek(const StringPiece& target) { 140 leveldb::Status LevelDBTransaction::DataIterator::Seek(
141 const StringPiece& target) {
140 iterator_ = data_->lower_bound(target); 142 iterator_ = data_->lower_bound(target);
143 return leveldb::Status::OK();
141 } 144 }
142 145
143 void LevelDBTransaction::DataIterator::Next() { 146 leveldb::Status LevelDBTransaction::DataIterator::Next() {
144 DCHECK(IsValid()); 147 DCHECK(IsValid());
145 ++iterator_; 148 ++iterator_;
149 return leveldb::Status::OK();
146 } 150 }
147 151
148 void LevelDBTransaction::DataIterator::Prev() { 152 leveldb::Status LevelDBTransaction::DataIterator::Prev() {
149 DCHECK(IsValid()); 153 DCHECK(IsValid());
150 if (iterator_ != data_->begin()) 154 if (iterator_ != data_->begin())
151 --iterator_; 155 --iterator_;
152 else 156 else
153 iterator_ = data_->end(); 157 iterator_ = data_->end();
158 return leveldb::Status::OK();
154 } 159 }
155 160
156 StringPiece LevelDBTransaction::DataIterator::Key() const { 161 StringPiece LevelDBTransaction::DataIterator::Key() const {
157 DCHECK(IsValid()); 162 DCHECK(IsValid());
158 return iterator_->first; 163 return iterator_->first;
159 } 164 }
160 165
161 StringPiece LevelDBTransaction::DataIterator::Value() const { 166 StringPiece LevelDBTransaction::DataIterator::Value() const {
162 DCHECK(IsValid()); 167 DCHECK(IsValid());
163 DCHECK(!IsDeleted()); 168 DCHECK(!IsDeleted());
(...skipping 30 matching lines...) Expand all
194 } 199 }
195 200
196 LevelDBTransaction::TransactionIterator::~TransactionIterator() { 201 LevelDBTransaction::TransactionIterator::~TransactionIterator() {
197 transaction_->UnregisterIterator(this); 202 transaction_->UnregisterIterator(this);
198 } 203 }
199 204
200 bool LevelDBTransaction::TransactionIterator::IsValid() const { 205 bool LevelDBTransaction::TransactionIterator::IsValid() const {
201 return !!current_; 206 return !!current_;
202 } 207 }
203 208
204 void LevelDBTransaction::TransactionIterator::SeekToLast() { 209 leveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() {
205 data_iterator_->SeekToLast(); 210 leveldb::Status s = data_iterator_->SeekToLast();
jsbell 2014/04/14 20:44:20 DCHECK(s.ok()) since data_iterator_ should never f
cmumford 2014/04/14 23:39:23 Yes, DataIterator::SeekToLast() always returns OK(
206 db_iterator_->SeekToLast(); 211 if (!s.ok())
212 return s;
213 s = db_iterator_->SeekToLast();
214 if (!s.ok())
215 return s;
207 direction_ = REVERSE; 216 direction_ = REVERSE;
208 217
209 HandleConflictsAndDeletes(); 218 HandleConflictsAndDeletes();
210 SetCurrentIteratorToLargestKey(); 219 SetCurrentIteratorToLargestKey();
220 return s;
211 } 221 }
212 222
213 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { 223 leveldb::Status LevelDBTransaction::TransactionIterator::Seek(
214 data_iterator_->Seek(target); 224 const StringPiece& target) {
215 db_iterator_->Seek(target); 225 leveldb::Status s = data_iterator_->Seek(target);
226 if (!s.ok())
227 return s;
228 s = db_iterator_->Seek(target);
229 if (!s.ok())
230 return s;
216 direction_ = FORWARD; 231 direction_ = FORWARD;
217 232
218 HandleConflictsAndDeletes(); 233 HandleConflictsAndDeletes();
219 SetCurrentIteratorToSmallestKey(); 234 SetCurrentIteratorToSmallestKey();
235 return s;
220 } 236 }
221 237
222 void LevelDBTransaction::TransactionIterator::Next() { 238 leveldb::Status LevelDBTransaction::TransactionIterator::Next() {
223 DCHECK(IsValid()); 239 DCHECK(IsValid());
224 if (data_changed_) 240 if (data_changed_)
225 RefreshDataIterator(); 241 RefreshDataIterator();
226 242
243 leveldb::Status s;
227 if (direction_ != FORWARD) { 244 if (direction_ != FORWARD) {
228 // Ensure the non-current iterator is positioned after Key(). 245 // Ensure the non-current iterator is positioned after Key().
229 246
230 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 247 LevelDBIterator* non_current = (current_ == db_iterator_.get())
231 ? data_iterator_.get() 248 ? data_iterator_.get()
232 : db_iterator_.get(); 249 : db_iterator_.get();
233 250
234 non_current->Seek(Key()); 251 non_current->Seek(Key());
235 if (non_current->IsValid() && 252 if (non_current->IsValid() &&
236 !comparator_->Compare(non_current->Key(), Key())) { 253 !comparator_->Compare(non_current->Key(), Key())) {
237 // Take an extra step so the non-current key is 254 // Take an extra step so the non-current key is
238 // strictly greater than Key(). 255 // strictly greater than Key().
239 non_current->Next(); 256 s = non_current->Next();
240 } 257 }
241 DCHECK(!non_current->IsValid() || 258 DCHECK(!non_current->IsValid() ||
242 comparator_->Compare(non_current->Key(), Key()) > 0); 259 comparator_->Compare(non_current->Key(), Key()) > 0);
243 260
244 direction_ = FORWARD; 261 direction_ = FORWARD;
245 } 262 }
246 263
247 current_->Next(); 264 if (s.ok())
248 HandleConflictsAndDeletes(); 265 s = current_->Next();
249 SetCurrentIteratorToSmallestKey(); 266 if (s.ok()) {
267 HandleConflictsAndDeletes();
268 SetCurrentIteratorToSmallestKey();
269 }
270 return s;
250 } 271 }
251 272
252 void LevelDBTransaction::TransactionIterator::Prev() { 273 leveldb::Status LevelDBTransaction::TransactionIterator::Prev() {
253 DCHECK(IsValid()); 274 DCHECK(IsValid());
275 leveldb::Status s;
254 if (data_changed_) 276 if (data_changed_)
255 RefreshDataIterator(); 277 RefreshDataIterator();
256 278
257 if (direction_ != REVERSE) { 279 if (direction_ != REVERSE) {
258 // Ensure the non-current iterator is positioned before Key(). 280 // Ensure the non-current iterator is positioned before Key().
259 281
260 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 282 LevelDBIterator* non_current = (current_ == db_iterator_.get())
261 ? data_iterator_.get() 283 ? data_iterator_.get()
262 : db_iterator_.get(); 284 : db_iterator_.get();
263 285
264 non_current->Seek(Key()); 286 s = non_current->Seek(Key());
jsbell 2014/04/14 20:44:20 Does s need to be tested here?
cmumford 2014/04/14 23:39:23 Done.
265 if (non_current->IsValid()) { 287 if (non_current->IsValid()) {
266 // Iterator is at first entry >= Key(). 288 // Iterator is at first entry >= Key().
267 // Step back once to entry < key. 289 // Step back once to entry < key.
268 // This is why we don't check for the keys being the same before 290 // This is why we don't check for the keys being the same before
269 // stepping, like we do in Next() above. 291 // stepping, like we do in Next() above.
270 non_current->Prev(); 292 non_current->Prev();
271 } else { 293 } else {
272 // Iterator has no entries >= Key(). Position at last entry. 294 // Iterator has no entries >= Key(). Position at last entry.
273 non_current->SeekToLast(); 295 non_current->SeekToLast();
274 } 296 }
275 DCHECK(!non_current->IsValid() || 297 DCHECK(!non_current->IsValid() ||
276 comparator_->Compare(non_current->Key(), Key()) < 0); 298 comparator_->Compare(non_current->Key(), Key()) < 0);
277 299
278 direction_ = REVERSE; 300 direction_ = REVERSE;
279 } 301 }
280 302
281 current_->Prev(); 303 if (s.ok())
jsbell 2014/04/14 20:44:20 This repeated testing of s.ok() is weird. Can we j
cmumford 2014/04/14 23:39:23 Done.
282 HandleConflictsAndDeletes(); 304 s = current_->Prev();
283 SetCurrentIteratorToLargestKey(); 305 if (s.ok()) {
306 HandleConflictsAndDeletes();
307 SetCurrentIteratorToLargestKey();
308 }
309 return s;
284 } 310 }
285 311
286 StringPiece LevelDBTransaction::TransactionIterator::Key() const { 312 StringPiece LevelDBTransaction::TransactionIterator::Key() const {
287 DCHECK(IsValid()); 313 DCHECK(IsValid());
288 if (data_changed_) 314 if (data_changed_)
289 RefreshDataIterator(); 315 RefreshDataIterator();
290 return current_->Key(); 316 return current_->Key();
291 } 317 }
292 318
293 StringPiece LevelDBTransaction::TransactionIterator::Value() const { 319 StringPiece LevelDBTransaction::TransactionIterator::Value() const {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 486
461 leveldb::Status s = db_->Write(*write_batch_); 487 leveldb::Status s = db_->Write(*write_batch_);
462 if (s.ok()) { 488 if (s.ok()) {
463 finished_ = true; 489 finished_ = true;
464 write_batch_->Clear(); 490 write_batch_->Clear();
465 } 491 }
466 return s; 492 return s;
467 } 493 }
468 494
469 } // namespace content 495 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698