Index: content/browser/indexed_db/indexed_db_database.cc |
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc |
index ca13e95dbc151c70c4cee6a548773d9e4f02b851..b802dfb1232f256699ec980ae59b8f8827c7f4d8 100644 |
--- a/content/browser/indexed_db/indexed_db_database.cc |
+++ b/content/browser/indexed_db/indexed_db_database.cc |
@@ -6,6 +6,7 @@ |
#include <math.h> |
+#include <algorithm> |
#include <limits> |
#include <set> |
@@ -1183,13 +1184,11 @@ static std::unique_ptr<IndexedDBKey> GenerateKey( |
IndexedDBTransaction* transaction, |
int64_t database_id, |
int64_t object_store_id) { |
- const int64_t max_generator_value = |
- 9007199254740992LL; // Maximum integer storable as ECMAScript number. |
+ // Maximum integer uniquely representable as ECMAScript number. |
+ const int64_t max_generator_value = 9007199254740992LL; |
int64_t current_number; |
leveldb::Status s = backing_store->GetKeyGeneratorCurrentNumber( |
- transaction->BackingStoreTransaction(), |
- database_id, |
- object_store_id, |
+ transaction->BackingStoreTransaction(), database_id, object_store_id, |
¤t_number); |
if (!s.ok()) { |
LOG(ERROR) << "Failed to GetKeyGeneratorCurrentNumber"; |
@@ -1201,6 +1200,10 @@ static std::unique_ptr<IndexedDBKey> GenerateKey( |
return base::MakeUnique<IndexedDBKey>(current_number, WebIDBKeyTypeNumber); |
} |
+// Called at the end of a "put" operation. The key is a number that was either |
+// generated by the generator which now needs to be incremented (so |
+// |check_current| is false) or was user-supplied so we only conditionally use |
+// (and |check_current| is true). |
static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store, |
IndexedDBTransaction* transaction, |
int64_t database_id, |
@@ -1208,9 +1211,13 @@ static leveldb::Status UpdateKeyGenerator(IndexedDBBackingStore* backing_store, |
const IndexedDBKey& key, |
bool check_current) { |
DCHECK_EQ(WebIDBKeyTypeNumber, key.type()); |
+ // Maximum integer uniquely representable as ECMAScript number. |
+ const double max_generator_value = 9007199254740992.0; |
+ int64_t value = base::saturated_cast<int64_t>( |
+ floor(std::min(key.number(), max_generator_value))); |
return backing_store->MaybeUpdateKeyGeneratorCurrentNumber( |
transaction->BackingStoreTransaction(), database_id, object_store_id, |
- static_cast<int64_t>(floor(key.number())) + 1, check_current); |
+ value + 1, check_current); |
} |
struct IndexedDBDatabase::PutOperationParams { |