LayoutTests/imported/w3c:
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jan 2016 21:37:35 +0000 (21:37 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jan 2016 21:37:35 +0000 (21:37 +0000)
Modern IDB: IDBBindingUtilities chokes on unicode strings for get/set.
https://bugs.webkit.org/show_bug.cgi?id=152921

Reviewed by Alex Christensen.

* indexeddb/keygenerator-overflow-expected.txt:

Source/WebCore:
Modern IDB: storage/indexeddb/key-generator.html fails.
https://bugs.webkit.org/show_bug.cgi?id=152981

Reviewed by Alex Christensen.

No new tests (One failing test now passes, and one test's results get a progression).

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::generateKeyNumber): Throw an error if the current
  value is already over 2^53.
(WebCore::IDBServer::MemoryIDBBackingStore::revertGeneratedKeyNumber):
(WebCore::IDBServer::MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber): Handle double -> uint64_t
  conversions properly when calculating the next key.
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::ScopeGuard::ScopeGuard): Add this utility class to call a function
  any time it goes out of scope.
(WebCore::IDBServer::ScopeGuard::~ScopeGuard):
(WebCore::IDBServer::ScopeGuard::enable):
(WebCore::IDBServer::ScopeGuard::disable):
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Revert the key generator value if
  the put/add operation ends in error.

LayoutTests:
Modern IDB: storage/indexeddb/key-generator.html fails.
https://bugs.webkit.org/show_bug.cgi?id=152981

Reviewed by Alex Christensen.

* platform/mac-wk1/TestExpectations:
* platform/wk2/imported/w3c/indexeddb/keygenerator-overflow-expected.txt: Copied from LayoutTests/imported/w3c/indexeddb/keygenerator-overflow-expected.txt.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194864 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/indexeddb/keygenerator-overflow-expected.txt
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/wk2/imported/w3c/indexeddb/keygenerator-overflow-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

index 3b53c3f..aa9f482 100644 (file)
@@ -1,5 +1,15 @@
 2016-01-11  Brady Eidson  <beidson@apple.com>
 
+        Modern IDB: storage/indexeddb/key-generator.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=152981
+
+        Reviewed by Alex Christensen.
+
+        * platform/mac-wk1/TestExpectations:
+        * platform/wk2/imported/w3c/indexeddb/keygenerator-overflow-expected.txt: Copied from LayoutTests/imported/w3c/indexeddb/keygenerator-overflow-expected.txt.
+
+2016-01-11  Brady Eidson  <beidson@apple.com>
+
         Modern IDB: storage/indexeddb/lazy-index-population.html fails.
         https://bugs.webkit.org/show_bug.cgi?id=152976
 
index be60604..dfd96d6 100644 (file)
@@ -1,3 +1,12 @@
+2016-01-11  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBBindingUtilities chokes on unicode strings for get/set.
+        https://bugs.webkit.org/show_bug.cgi?id=152921
+
+        Reviewed by Alex Christensen.
+
+        * indexeddb/keygenerator-overflow-expected.txt:
+
 2016-01-08  Brady Eidson  <beidson@apple.com>
 
         Modern IDB: IDBBindingUtilities chokes on unicode strings for get/set.
index d40a356..2597835 100644 (file)
@@ -1,3 +1,3 @@
 
-FAIL Keygenerator overflow assert_unreached: When "current number" overflows, error event is expected Reached unreachable code
+PASS Keygenerator overflow 
 
index 5e67eba..270c1c6 100644 (file)
@@ -76,9 +76,6 @@ imported/w3c/indexeddb/idbindex_getKey7.htm [ Failure ]
 imported/w3c/indexeddb/idbindex_openCursor2.htm [ Failure ]
 imported/w3c/indexeddb/idbindex_openKeyCursor3.htm [ Failure ]
 
-# Modern IDB doesn't properly handle 2^53 as a key generator value
-storage/indexeddb/key-generator.html [ Skip ]
-
 # Crashes with GuardMalloc or ASan
 storage/indexeddb/index-multientry.html [ Skip ]
 
diff --git a/LayoutTests/platform/wk2/imported/w3c/indexeddb/keygenerator-overflow-expected.txt b/LayoutTests/platform/wk2/imported/w3c/indexeddb/keygenerator-overflow-expected.txt
new file mode 100644 (file)
index 0000000..d40a356
--- /dev/null
@@ -0,0 +1,3 @@
+
+FAIL Keygenerator overflow assert_unreached: When "current number" overflows, error event is expected Reached unreachable code
+
index 85f39a0..44a83a1 100644 (file)
@@ -1,5 +1,33 @@
 2016-01-11  Brady Eidson  <beidson@apple.com>
 
+        Modern IDB: storage/indexeddb/key-generator.html fails.
+        https://bugs.webkit.org/show_bug.cgi?id=152981
+
+        Reviewed by Alex Christensen.
+
+        No new tests (One failing test now passes, and one test's results get a progression).
+
+        * Modules/indexeddb/server/IDBBackingStore.h:
+        
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::generateKeyNumber): Throw an error if the current
+          value is already over 2^53.
+        (WebCore::IDBServer::MemoryIDBBackingStore::revertGeneratedKeyNumber):
+        (WebCore::IDBServer::MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber): Handle double -> uint64_t
+          conversions properly when calculating the next key.
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::ScopeGuard::ScopeGuard): Add this utility class to call a function 
+          any time it goes out of scope.
+        (WebCore::IDBServer::ScopeGuard::~ScopeGuard):
+        (WebCore::IDBServer::ScopeGuard::enable):
+        (WebCore::IDBServer::ScopeGuard::disable):
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd): Revert the key generator value if
+          the put/add operation ends in error.
+
+2016-01-11  Brady Eidson  <beidson@apple.com>
+
         Modern IDB: storage/indexeddb/lazy-index-population.html fails.
         https://bugs.webkit.org/show_bug.cgi?id=152976
 
index 0a1f01b..94c04af 100644 (file)
@@ -72,6 +72,7 @@ public:
     virtual IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) = 0;
     virtual IDBError getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&, uint64_t& outCount) = 0;
     virtual IDBError generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t& keyNumber) = 0;
+    virtual IDBError revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber) = 0;
     virtual IDBError maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber) = 0;
     virtual IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) = 0;
     virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) = 0;
index bcc67e9..d63e694 100644 (file)
@@ -38,6 +38,9 @@
 namespace WebCore {
 namespace IDBServer {
 
+// The IndexedDB spec states the value you can get from the key generator is 2^53
+static uint64_t maxGeneratedKeyValue = 0x20000000000000;
+
 std::unique_ptr<MemoryIDBBackingStore> MemoryIDBBackingStore::create(const IDBDatabaseIdentifier& identifier)
 {
     return std::make_unique<MemoryIDBBackingStore>(identifier);
@@ -343,11 +346,29 @@ IDBError MemoryIDBBackingStore::generateKeyNumber(const IDBResourceIdentifier& t
     RELEASE_ASSERT(objectStore);
 
     keyNumber = objectStore->currentKeyGeneratorValue();
+    if (keyNumber > maxGeneratedKeyValue)
+        return { IDBDatabaseException::ConstraintError, "Cannot generate new key value over 2^53 for object store operation" };
+
     objectStore->setKeyGeneratorValue(keyNumber + 1);
 
     return IDBError();
 }
 
+IDBError MemoryIDBBackingStore::revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber)
+{
+    LOG(IndexedDB, "MemoryIDBBackingStore::revertGeneratedKeyNumber");
+    ASSERT(objectStoreIdentifier);
+    ASSERT_UNUSED(transactionIdentifier, m_transactions.contains(transactionIdentifier));
+    ASSERT_UNUSED(transactionIdentifier, m_transactions.get(transactionIdentifier)->isWriting());
+
+    MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
+    RELEASE_ASSERT(objectStore);
+
+    objectStore->setKeyGeneratorValue(keyNumber);
+
+    return { };
+}
+
 IDBError MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber)
 {
     LOG(IndexedDB, "MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber");
@@ -362,10 +383,10 @@ IDBError MemoryIDBBackingStore::maybeUpdateKeyGeneratorNumber(const IDBResourceI
         return { };
 
     uint64_t newKeyInteger(newKeyNumber);
-    if (newKeyInteger <= newKeyNumber)
+    if (newKeyInteger <= uint64_t(newKeyNumber))
         ++newKeyInteger;
 
-    ASSERT(newKeyInteger > newKeyNumber);
+    ASSERT(newKeyInteger > uint64_t(newKeyNumber));
 
     objectStore->setKeyGeneratorValue(newKeyInteger);
 
index 3cc239b..0b06abe 100644 (file)
@@ -64,6 +64,7 @@ public:
     virtual IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) override final;
     virtual IDBError getCount(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&, uint64_t& outCount) override final;
     virtual IDBError generateKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t& keyNumber) override final;
+    virtual IDBError revertGeneratedKeyNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t keyNumber) override final;
     virtual IDBError maybeUpdateKeyGeneratorNumber(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, double newKeyNumber) override final;
     virtual IDBError openCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBCursorInfo&, IDBGetResult& outResult) override final;
     virtual IDBError iterateCursor(const IDBResourceIdentifier& transactionIdentifier, const IDBResourceIdentifier& cursorIdentifier, const IDBKeyData&, uint32_t count, IDBGetResult& outResult) override final;
index 223239b..f69802e 100644 (file)
@@ -653,6 +653,37 @@ ExecState& UniqueIDBDatabase::databaseThreadExecState()
     return *globalObject.get()->globalExec();
 }
 
+class ScopeGuard {
+public:
+    ScopeGuard()
+    {
+    }
+
+    ScopeGuard(std::function<void()> function)
+        : m_function(WTFMove(function))
+    {
+    }
+
+    ~ScopeGuard()
+    {
+        if (m_function)
+            m_function();
+    }
+
+    void enable(std::function<void()> function)
+    {
+        m_function = WTFMove(function);
+    }
+
+    void disable()
+    {
+        m_function = nullptr;
+    }
+
+private:
+    std::function<void()> m_function { nullptr };
+};
+
 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const ThreadSafeDataBuffer& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     ASSERT(!isMainThread());
@@ -672,6 +703,7 @@ void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBRe
     }
 
     bool usedKeyIsGenerated = false;
+    ScopeGuard generatedKeyResetter;
     if (objectStoreInfo->autoIncrement() && !keyData.isValid()) {
         uint64_t keyNumber;
         error = m_backingStore->generateKeyNumber(transactionIdentifier, objectStoreIdentifier, keyNumber);
@@ -682,6 +714,9 @@ void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBRe
         
         usedKey.setNumberValue(keyNumber);
         usedKeyIsGenerated = true;
+        generatedKeyResetter.enable([this, transactionIdentifier, objectStoreIdentifier, keyNumber]() {
+            m_backingStore->revertGeneratedKeyNumber(transactionIdentifier, objectStoreIdentifier, keyNumber);
+        });
     } else
         usedKey = keyData;
 
@@ -743,6 +778,7 @@ void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBRe
     if (overwriteMode != IndexedDB::ObjectStoreOverwriteMode::OverwriteForCursor && objectStoreInfo->autoIncrement() && keyData.type() == IndexedDB::KeyType::Number)
         error = m_backingStore->maybeUpdateKeyGeneratorNumber(transactionIdentifier, objectStoreIdentifier, keyData.number());
 
+    generatedKeyResetter.disable();
     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
 }