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

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: 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/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();
206 db_iterator_->SeekToLast(); 211 DCHECK(s.ok());
212 s = db_iterator_->SeekToLast();
213 if (!s.ok())
214 return s;
207 direction_ = REVERSE; 215 direction_ = REVERSE;
208 216
209 HandleConflictsAndDeletes(); 217 HandleConflictsAndDeletes();
210 SetCurrentIteratorToLargestKey(); 218 SetCurrentIteratorToLargestKey();
219 return s;
211 } 220 }
212 221
213 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { 222 leveldb::Status LevelDBTransaction::TransactionIterator::Seek(
214 data_iterator_->Seek(target); 223 const StringPiece& target) {
215 db_iterator_->Seek(target); 224 leveldb::Status s = data_iterator_->Seek(target);
225 DCHECK(s.ok());
226 s = db_iterator_->Seek(target);
227 if (!s.ok())
228 return s;
216 direction_ = FORWARD; 229 direction_ = FORWARD;
217 230
218 HandleConflictsAndDeletes(); 231 HandleConflictsAndDeletes();
219 SetCurrentIteratorToSmallestKey(); 232 SetCurrentIteratorToSmallestKey();
233 return s;
220 } 234 }
221 235
222 void LevelDBTransaction::TransactionIterator::Next() { 236 leveldb::Status LevelDBTransaction::TransactionIterator::Next() {
223 DCHECK(IsValid()); 237 DCHECK(IsValid());
224 if (data_changed_) 238 if (data_changed_)
225 RefreshDataIterator(); 239 RefreshDataIterator();
226 240
241 leveldb::Status s;
227 if (direction_ != FORWARD) { 242 if (direction_ != FORWARD) {
228 // Ensure the non-current iterator is positioned after Key(). 243 // Ensure the non-current iterator is positioned after Key().
229 244
230 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 245 LevelDBIterator* non_current = (current_ == db_iterator_.get())
231 ? data_iterator_.get() 246 ? data_iterator_.get()
232 : db_iterator_.get(); 247 : db_iterator_.get();
233 248
234 non_current->Seek(Key()); 249 non_current->Seek(Key());
235 if (non_current->IsValid() && 250 if (non_current->IsValid() &&
236 !comparator_->Compare(non_current->Key(), Key())) { 251 !comparator_->Compare(non_current->Key(), Key())) {
237 // Take an extra step so the non-current key is 252 // Take an extra step so the non-current key is
238 // strictly greater than Key(). 253 // strictly greater than Key().
239 non_current->Next(); 254 s = non_current->Next();
255 if (!s.ok())
256 return s;
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 s = current_->Next();
265 if (!s.ok())
266 return s;
248 HandleConflictsAndDeletes(); 267 HandleConflictsAndDeletes();
249 SetCurrentIteratorToSmallestKey(); 268 SetCurrentIteratorToSmallestKey();
269 return leveldb::Status::OK();
250 } 270 }
251 271
252 void LevelDBTransaction::TransactionIterator::Prev() { 272 leveldb::Status LevelDBTransaction::TransactionIterator::Prev() {
253 DCHECK(IsValid()); 273 DCHECK(IsValid());
274 leveldb::Status s;
254 if (data_changed_) 275 if (data_changed_)
255 RefreshDataIterator(); 276 RefreshDataIterator();
256 277
257 if (direction_ != REVERSE) { 278 if (direction_ != REVERSE) {
258 // Ensure the non-current iterator is positioned before Key(). 279 // Ensure the non-current iterator is positioned before Key().
259 280
260 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 281 LevelDBIterator* non_current = (current_ == db_iterator_.get())
261 ? data_iterator_.get() 282 ? data_iterator_.get()
262 : db_iterator_.get(); 283 : db_iterator_.get();
263 284
264 non_current->Seek(Key()); 285 s = non_current->Seek(Key());
286 if (!s.ok())
287 return s;
265 if (non_current->IsValid()) { 288 if (non_current->IsValid()) {
266 // Iterator is at first entry >= Key(). 289 // Iterator is at first entry >= Key().
267 // Step back once to entry < key. 290 // Step back once to entry < key.
268 // This is why we don't check for the keys being the same before 291 // This is why we don't check for the keys being the same before
269 // stepping, like we do in Next() above. 292 // stepping, like we do in Next() above.
270 non_current->Prev(); 293 non_current->Prev();
271 } else { 294 } else {
272 // Iterator has no entries >= Key(). Position at last entry. 295 // Iterator has no entries >= Key(). Position at last entry.
273 non_current->SeekToLast(); 296 non_current->SeekToLast();
274 } 297 }
275 DCHECK(!non_current->IsValid() || 298 DCHECK(!non_current->IsValid() ||
276 comparator_->Compare(non_current->Key(), Key()) < 0); 299 comparator_->Compare(non_current->Key(), Key()) < 0);
277 300
278 direction_ = REVERSE; 301 direction_ = REVERSE;
279 } 302 }
280 303
281 current_->Prev(); 304 s = current_->Prev();
305 if (!s.ok())
306 return s;
282 HandleConflictsAndDeletes(); 307 HandleConflictsAndDeletes();
283 SetCurrentIteratorToLargestKey(); 308 SetCurrentIteratorToLargestKey();
309 return leveldb::Status::OK();
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