IndexedDB: breaks if binary data (Uint8Array) and autoIncrement key in store
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:45:17 +0000 (18:45 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:45:17 +0000 (18:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185869
<rdar://problem/40453623>

Reviewed by Geoffrey Garen.

Source/WebCore:

lexicalGlobalObject is casted to JSDOMGlobalObject in CloneSerializer::dumpArrayBufferView,
so we should use JSDOMGlobalObject instead of JSGlobalObject in IDB database thread.

Covered by modified test: storage/indexeddb/objectstore-autoincrement.html

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::databaseThreadVM):
(WebCore::IDBServer::UniqueIDBDatabase::databaseThreadExecState):
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::create):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/JSDOMWrapper.cpp:
(WebCore::JSDOMObject::JSDOMObject):

LayoutTests:

* storage/indexeddb/objectstore-autoincrement-expected.txt:
* storage/indexeddb/objectstore-autoincrement-private-expected.txt:
* storage/indexeddb/resources/objectstore-autoincrement.js:
(getLincolnAfterInjectedKeySuccess):
(putBobSuccess):
(getBobSuccess):
(addLincolnWithExplicitKeySuccess):
(putAbrahamSuccess):

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

LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/objectstore-autoincrement-expected.txt
LayoutTests/storage/indexeddb/objectstore-autoincrement-private-expected.txt
LayoutTests/storage/indexeddb/resources/objectstore-autoincrement.js
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Source/WebCore/bindings/js/JSDOMGlobalObject.h
Source/WebCore/bindings/js/JSDOMWrapper.cpp

index 67b64a5..bb2f287 100644 (file)
@@ -1,5 +1,22 @@
 2018-11-29  Sihui Liu  <sihui_liu@apple.com>
 
+        IndexedDB: breaks if binary data (Uint8Array) and autoIncrement key in store
+        https://bugs.webkit.org/show_bug.cgi?id=185869
+        <rdar://problem/40453623>
+
+        Reviewed by Geoffrey Garen.
+
+        * storage/indexeddb/objectstore-autoincrement-expected.txt:
+        * storage/indexeddb/objectstore-autoincrement-private-expected.txt:
+        * storage/indexeddb/resources/objectstore-autoincrement.js:
+        (getLincolnAfterInjectedKeySuccess):
+        (putBobSuccess):
+        (getBobSuccess):
+        (addLincolnWithExplicitKeySuccess):
+        (putAbrahamSuccess):
+
+2018-11-29  Sihui Liu  <sihui_liu@apple.com>
+
         Unexpected constructor / instanceof  behavior when retrieving indexedDB data in an iframe
         https://bugs.webkit.org/show_bug.cgi?id=185906
         <rdar://problem/40583100>
index 230f3f4..0ab0f1a 100644 (file)
@@ -35,19 +35,26 @@ getLincolnAfterInjectedKeySuccess():
 PASS event.target.result.name is "Lincoln"
 PASS event.target.result.number is "7012"
 PASS event.target.result.id is 4
+store.add({name: 'Bob', number: Uint8Array.from([100, 101])})
+putBobSuccess():
+PASS event.target.result is 5
+store.get(5)
+getBobSuccess():
+PASS event.target.result.name is "Bob"
+PASS event.target.result.number is [100, 101]
 store = trans.objectStore('StoreWithAutoIncrement')
 Insert into object store with key gen using explicit key
-store.add({name: 'Lincoln', number: '7012'}, 5)
+store.add({name: 'Lincoln', number: '7012'}, 6)
 addLincolnWithExplicitKeySuccess():
-PASS event.target.result is 5
-store.get(5)
+PASS event.target.result is 6
+store.get(6)
 getLincolnSuccess():
 PASS event.target.result.name is "Lincoln"
 PASS event.target.result.number is "7012"
 store.put({name: 'Abraham', number: '2107'})
 putAbrahamSuccess():
-PASS event.target.result is 6
-store.get(6)
+PASS event.target.result is 7
+store.get(7)
 getAbrahamSuccess():
 PASS event.target.result.name is "Abraham"
 PASS event.target.result.number is "2107"
index 230f3f4..0ab0f1a 100644 (file)
@@ -35,19 +35,26 @@ getLincolnAfterInjectedKeySuccess():
 PASS event.target.result.name is "Lincoln"
 PASS event.target.result.number is "7012"
 PASS event.target.result.id is 4
+store.add({name: 'Bob', number: Uint8Array.from([100, 101])})
+putBobSuccess():
+PASS event.target.result is 5
+store.get(5)
+getBobSuccess():
+PASS event.target.result.name is "Bob"
+PASS event.target.result.number is [100, 101]
 store = trans.objectStore('StoreWithAutoIncrement')
 Insert into object store with key gen using explicit key
-store.add({name: 'Lincoln', number: '7012'}, 5)
+store.add({name: 'Lincoln', number: '7012'}, 6)
 addLincolnWithExplicitKeySuccess():
-PASS event.target.result is 5
-store.get(5)
+PASS event.target.result is 6
+store.get(6)
 getLincolnSuccess():
 PASS event.target.result.name is "Lincoln"
 PASS event.target.result.number is "7012"
 store.put({name: 'Abraham', number: '2107'})
 putAbrahamSuccess():
-PASS event.target.result is 6
-store.get(6)
+PASS event.target.result is 7
+store.get(7)
 getAbrahamSuccess():
 PASS event.target.result.name is "Abraham"
 PASS event.target.result.number is "2107"
index a478aa1..894ced9 100644 (file)
@@ -70,9 +70,30 @@ function getLincolnAfterInjectedKeySuccess()
     shouldBeEqualToString("event.target.result.number", "7012");
     shouldBe("event.target.result.id", "4");
 
+    request = evalAndLog("store.add({name: 'Bob', number: Uint8Array.from([100, 101])})");
+    request.onsuccess = putBobSuccess;
+    request.onerror = unexpectedErrorCallback;
+}
+
+function putBobSuccess()
+{
+    debug("putBobSuccess():");
+    shouldBe("event.target.result", "5");
+
+    request = evalAndLog("store.get(5)");
+    request.onsuccess = getBobSuccess;
+    request.onerror = unexpectedErrorCallback;
+}
+
+function getBobSuccess()
+{
+    debug("getBobSuccess():");
+    shouldBeEqualToString("event.target.result.name", "Bob");
+    shouldBe("event.target.result.number", "[100, 101]");
+
     self.store = evalAndLog("store = trans.objectStore('StoreWithAutoIncrement')");
     debug("Insert into object store with key gen using explicit key");
-    request = evalAndLog("store.add({name: 'Lincoln', number: '7012'}, 5)");
+    request = evalAndLog("store.add({name: 'Lincoln', number: '7012'}, 6)");
     request.onsuccess = addLincolnWithExplicitKeySuccess;
     request.onerror = unexpectedErrorCallback;
 }
@@ -80,9 +101,9 @@ function getLincolnAfterInjectedKeySuccess()
 function addLincolnWithExplicitKeySuccess()
 {
     debug("addLincolnWithExplicitKeySuccess():");
-    shouldBe("event.target.result", "5");
+    shouldBe("event.target.result", "6");
 
-    request = evalAndLog("store.get(5)");
+    request = evalAndLog("store.get(6)");
     request.onsuccess = getLincolnSuccess;
     request.onerror = unexpectedErrorCallback;
 }
@@ -101,9 +122,9 @@ function getLincolnSuccess()
 function putAbrahamSuccess()
 {
     debug("putAbrahamSuccess():");
-    shouldBe("event.target.result", "6");
+    shouldBe("event.target.result", "7");
 
-    request = evalAndLog("store.get(6)");
+    request = evalAndLog("store.get(7)");
     request.onsuccess = getAbrahamSuccess;
     request.onerror = unexpectedErrorCallback;
 }
index e00d298..8f8f38b 100644 (file)
@@ -1,5 +1,27 @@
 2018-11-29  Sihui Liu  <sihui_liu@apple.com>
 
+        IndexedDB: breaks if binary data (Uint8Array) and autoIncrement key in store
+        https://bugs.webkit.org/show_bug.cgi?id=185869
+        <rdar://problem/40453623>
+
+        Reviewed by Geoffrey Garen.
+
+        lexicalGlobalObject is casted to JSDOMGlobalObject in CloneSerializer::dumpArrayBufferView, 
+        so we should use JSDOMGlobalObject instead of JSGlobalObject in IDB database thread.
+
+        Covered by modified test: storage/indexeddb/objectstore-autoincrement.html
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadVM):
+        (WebCore::IDBServer::UniqueIDBDatabase::databaseThreadExecState):
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::create):
+        * bindings/js/JSDOMGlobalObject.h:
+        * bindings/js/JSDOMWrapper.cpp:
+        (WebCore::JSDOMObject::JSDOMObject):
+
+2018-11-29  Sihui Liu  <sihui_liu@apple.com>
+
         Unexpected constructor / instanceof  behavior when retrieving indexedDB data in an iframe
         https://bugs.webkit.org/show_bug.cgi?id=185906
         <rdar://problem/40583100>
index d4590c6..fc07ef1 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "DOMWrapperWorld.h"
 #include "IDBBindingUtilities.h"
 #include "IDBCursorInfo.h"
 #include "IDBGetAllRecordsData.h"
@@ -42,6 +43,7 @@
 #include "Logging.h"
 #include "SerializedScriptValue.h"
 #include "UniqueIDBDatabaseConnection.h"
+#include "WebCoreJSClientData.h"
 #include <JavaScriptCore/AuxiliaryBarrierInlines.h>
 #include <JavaScriptCore/HeapInlines.h>
 #include <JavaScriptCore/StrongInlines.h>
@@ -938,6 +940,11 @@ VM& UniqueIDBDatabase::databaseThreadVM()
 {
     ASSERT(!isMainThread());
     static VM* vm = &VM::create().leakRef();
+    if (!vm->heap.hasAccess()) {
+        vm->heap.acquireAccess();
+        JSVMClientData::initNormalWorld(vm);
+    }
+
     return *vm;
 }
 
@@ -945,10 +952,10 @@ ExecState& UniqueIDBDatabase::databaseThreadExecState()
 {
     ASSERT(!isMainThread());
 
-    static NeverDestroyed<Strong<JSGlobalObject>> globalObject(databaseThreadVM(), JSGlobalObject::create(databaseThreadVM(), JSGlobalObject::createStructure(databaseThreadVM(), jsNull())));
+    static NeverDestroyed<Strong<JSDOMGlobalObject>> domGlobalObject(databaseThreadVM(), JSDOMGlobalObject::create(databaseThreadVM(), JSDOMGlobalObject::createStructure(databaseThreadVM(), jsNull()), normalWorld(databaseThreadVM())));
 
-    RELEASE_ASSERT(globalObject.get()->globalExec());
-    return *globalObject.get()->globalExec();
+    RELEASE_ASSERT(domGlobalObject.get()->globalExec());
+    return *domGlobalObject.get()->globalExec();
 }
 
 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
index 5d8842b..765eedc 100644 (file)
@@ -76,6 +76,13 @@ void JSDOMGlobalObject::destroy(JSCell* cell)
     static_cast<JSDOMGlobalObject*>(cell)->JSDOMGlobalObject::~JSDOMGlobalObject();
 }
 
+JSDOMGlobalObject* JSDOMGlobalObject::create(JSC::VM& vm, JSC::Structure* structure, Ref<DOMWrapperWorld>&& world)
+{
+    JSDOMGlobalObject* domGlobalObject = new (NotNull, JSC::allocateCell<JSDOMGlobalObject>(vm.heap)) JSDOMGlobalObject(vm, structure, WTFMove(world));
+    domGlobalObject->finishCreation(vm);
+    return domGlobalObject;
+}
+
 EncodedJSValue JSC_HOST_CALL makeThisTypeErrorForBuiltins(ExecState* execState)
 {
     ASSERT(execState);
index ed52551..ac6928f 100644 (file)
@@ -53,6 +53,8 @@ protected:
     void finishCreation(JSC::VM&, JSC::JSObject*);
 
 public:
+    static JSDOMGlobalObject* create(JSC::VM&, JSC::Structure*, Ref<DOMWrapperWorld>&&);
+
     Lock& gcLock() { return m_gcLock; }
 
     JSDOMStructureMap& structures(const AbstractLocker&) { return m_structures; }
index 89a3080..19fcd77 100644 (file)
@@ -41,7 +41,7 @@ STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSDOMObject);
 JSDOMObject::JSDOMObject(JSC::Structure* structure, JSC::JSGlobalObject& globalObject)
     : Base(globalObject.vm(), structure)
 {
-    ASSERT(scriptExecutionContext() || globalObject.classInfo() == JSRemoteDOMWindow::info());
+    ASSERT(globalObject.classInfo() == JSDOMGlobalObject::info() || scriptExecutionContext() || globalObject.classInfo() == JSRemoteDOMWindow::info());
 }
 
 CompleteSubspace* outputConstraintSubspaceFor(VM& vm)