REGRESSION (r244436): IndexedDB Uint8Array returned as ArrayBuffer
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jun 2019 23:45:41 +0000 (23:45 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jun 2019 23:45:41 +0000 (23:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=198738
<rdar://problem/51614053>

Reviewed by Brady Eidson.

In InexedDB, two binary keys are the same as long as their data is the same.

Modified tests: storage/indexeddb/key-type-binary.html
                storage/indexeddb/key-type-binary-private.html

* bindings/js/IDBBindingUtilities.cpp:
(WebCore::injectIDBKeyIntoScriptValue):
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::readArrayBufferView):

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

LayoutTests/storage/indexeddb/key-type-binary-expected.txt
LayoutTests/storage/indexeddb/key-type-binary-private-expected.txt
LayoutTests/storage/indexeddb/resources/key-type-binary.js
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/IDBBindingUtilities.cpp
Source/WebCore/bindings/js/SerializedScriptValue.cpp

index ee0e3e4..2c22cf4 100644 (file)
@@ -8,6 +8,7 @@ indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.
 indexedDB.deleteDatabase(dbname)
 indexedDB.open(dbname)
 db.createObjectStore('store');
+db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'});
 
 
 testBinaryKeys1():
@@ -53,6 +54,60 @@ store.put('value', new Float64Array([1,2,3]))
 store.put('value', new Uint8Array([1,2,3]).buffer)
 
 store.put('value', new DataView(new Uint8Array([1,2,3]).buffer))
+
+testBinaryKeys3():
+trans = db.transaction('storeWithKeyPath', 'readwrite')
+store = trans.objectStore('storeWithKeyPath')
+
+binary = new Uint8ClampedArray([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint16Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int8Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int16Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Float32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Float64Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint8Array([1,2,3]).buffer
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new DataView(new Uint8Array([1,2,3]).buffer)
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
index ee0e3e4..2c22cf4 100644 (file)
@@ -8,6 +8,7 @@ indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.
 indexedDB.deleteDatabase(dbname)
 indexedDB.open(dbname)
 db.createObjectStore('store');
+db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'});
 
 
 testBinaryKeys1():
@@ -53,6 +54,60 @@ store.put('value', new Float64Array([1,2,3]))
 store.put('value', new Uint8Array([1,2,3]).buffer)
 
 store.put('value', new DataView(new Uint8Array([1,2,3]).buffer))
+
+testBinaryKeys3():
+trans = db.transaction('storeWithKeyPath', 'readwrite')
+store = trans.objectStore('storeWithKeyPath')
+
+binary = new Uint8ClampedArray([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint16Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int8Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int16Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Int32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Float32Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Float64Array([1,2,3])
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new Uint8Array([1,2,3]).buffer
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
+
+binary = new DataView(new Uint8Array([1,2,3]).buffer)
+store.put({ binary })
+request = store.get(binary)
+PASS binary.constructor === request.result.binary.constructor is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c3f23f5..63318ed 100644 (file)
@@ -11,6 +11,7 @@ function prepareDatabase()
     db = event.target.result;
     event.target.transaction.onabort = unexpectedAbortCallback;
     objectStore = evalAndLog("db.createObjectStore('store');");
+    objectStoreWithKeyPath = evalAndLog("db.createObjectStore('storeWithKeyPath', {keyPath: 'binary'});");
     debug("");
 }
 
@@ -46,29 +47,54 @@ function testBinaryKeys1()
     trans.oncomplete = testBinaryKeys2;
 }
 
+const cases = [
+    "new Uint8ClampedArray([1,2,3])",
+    "new Uint16Array([1,2,3])",
+    "new Uint32Array([1,2,3])",
+    "new Int8Array([1,2,3])",
+    "new Int16Array([1,2,3])",
+    "new Int32Array([1,2,3])",
+    "new Float32Array([1,2,3])",
+    "new Float64Array([1,2,3])",
+    "new Uint8Array([1,2,3]).buffer",
+    "new DataView(new Uint8Array([1,2,3]).buffer)"
+];
+
 function testBinaryKeys2()
 {
     preamble();
     evalAndLog("trans = db.transaction('store', 'readwrite')");
     evalAndLog("store = trans.objectStore('store')");
 
-    var cases = [
-        "new Uint8ClampedArray([1,2,3])",
-        "new Uint16Array([1,2,3])",
-        "new Uint32Array([1,2,3])",
-        "new Int8Array([1,2,3])",
-        "new Int16Array([1,2,3])",
-        "new Int32Array([1,2,3])",
-        "new Float32Array([1,2,3])",
-        "new Float64Array([1,2,3])",
-        "new Uint8Array([1,2,3]).buffer",
-        "new DataView(new Uint8Array([1,2,3]).buffer)"
-    ];
-
     cases.forEach(function(testCase) {
         debug("");
         evalAndLog("store.put('value', " + testCase + ")");
     });
 
-    finishJSTest();
+    trans.oncomplete = testBinaryKeys3;
 }
+
+function runTest(testNumber) {
+    debug("");
+    evalAndLog("binary = " + cases[testNumber]);
+    evalAndLog("store.put({ binary })");
+    evalAndLog("request = store.get(binary)");
+    request.onsuccess = ()=>{
+        shouldBeTrue("binary.constructor === request.result.binary.constructor");
+
+        if (++testNumber == cases.length)
+            finishJSTest();
+        else
+            runTest(testNumber);
+    }
+    request.onerror = unexpectedErrorCallback;
+}
+
+function testBinaryKeys3()
+{
+    preamble();
+    evalAndLog("trans = db.transaction('storeWithKeyPath', 'readwrite')");
+    evalAndLog("store = trans.objectStore('storeWithKeyPath')");
+
+    runTest(0);
+}
\ No newline at end of file
index 16b61cd..61d99a0 100644 (file)
@@ -1,5 +1,23 @@
 2019-06-24  Sihui Liu  <sihui_liu@apple.com>
 
+        REGRESSION (r244436): IndexedDB Uint8Array returned as ArrayBuffer
+        https://bugs.webkit.org/show_bug.cgi?id=198738
+        <rdar://problem/51614053>
+
+        Reviewed by Brady Eidson.
+
+        In InexedDB, two binary keys are the same as long as their data is the same.
+
+        Modified tests: storage/indexeddb/key-type-binary.html
+                        storage/indexeddb/key-type-binary-private.html
+
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::injectIDBKeyIntoScriptValue):
+        * bindings/js/SerializedScriptValue.cpp:
+        (WebCore::CloneDeserializer::readArrayBufferView):
+
+2019-06-24  Sihui Liu  <sihui_liu@apple.com>
+
         Remove WebSQL quirk for nytimes.com
         https://bugs.webkit.org/show_bug.cgi?id=199175
 
index ad9234c..1a62553 100644 (file)
@@ -327,11 +327,9 @@ bool injectIDBKeyIntoScriptValue(ExecState& exec, const IDBKeyData& keyData, JSV
         return false;
 
     // Do not set if object already has the correct property value.
-    auto jsKey = toJS(exec, *exec.lexicalGlobalObject(), key.get());
     JSValue existingKey;
-    if (get(exec, parent, keyPathElements.last(), existingKey) && existingKey == jsKey)
+    if (get(exec, parent, keyPathElements.last(), existingKey) && !key->compare(createIDBKeyFromValue(exec, existingKey)))
         return true;
-
     if (!set(exec, parent, keyPathElements.last(), toJS(exec, *exec.lexicalGlobalObject(), key.get())))
         return false;
 
index c4600f8..965ece3 100644 (file)
@@ -2136,7 +2136,7 @@ private:
         RefPtr<ArrayBuffer> arrayBuffer = toPossiblySharedArrayBuffer(vm, arrayBufferObj);
         switch (arrayBufferViewSubtag) {
         case DataViewTag:
-            arrayBufferView = getJSValue(DataView::create(WTFMove(arrayBuffer), byteOffset, length).get());
+            arrayBufferView = toJS(m_exec, m_globalObject, DataView::create(WTFMove(arrayBuffer), byteOffset, length).get());
             return true;
         case Int8ArrayTag:
             arrayBufferView = toJS(m_exec, m_globalObject, Int8Array::tryCreate(WTFMove(arrayBuffer), byteOffset, length).get());