Unexpected constructor / instanceof behavior when retrieving indexedDB data in an...
authorsihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:41:48 +0000 (18:41 +0000)
committersihui_liu@apple.com <sihui_liu@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2018 18:41:48 +0000 (18:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=185906
<rdar://problem/40583100>

Reviewed by Geoffrey Garen.

Source/WebCore:

ScriptExecutionContext::execState() returned state of main frame, so deserialization of
IDBValue in iframe used constructors of main frame, which is wrong.

Test: storage/indexeddb/instanceof-iframe.html

* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::execState):

LayoutTests:

* storage/indexeddb/instanceof-iframe-expected.txt: Added.
* storage/indexeddb/instanceof-iframe.html: Added.
* storage/indexeddb/resources/instanceof-iframe.js: Added.
(test.else.shouldBe):
(test.else.shouldBeTrue):
(test.else.shouldBeFalse):
(test.else.evalAndLog):
(test):
(callback):

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

LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/instanceof-iframe-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/instanceof-iframe.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/resources/instanceof-iframe.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/ScriptExecutionContext.cpp

index eebab66..67b64a5 100644 (file)
@@ -1,3 +1,21 @@
+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>
+
+        Reviewed by Geoffrey Garen.
+
+        * storage/indexeddb/instanceof-iframe-expected.txt: Added.
+        * storage/indexeddb/instanceof-iframe.html: Added.
+        * storage/indexeddb/resources/instanceof-iframe.js: Added.
+        (test.else.shouldBe):
+        (test.else.shouldBeTrue):
+        (test.else.shouldBeFalse):
+        (test.else.evalAndLog):
+        (test):
+        (callback):
+
 2018-11-28  Dean Jackson  <dino@apple.com>
 
         [ES Modules] Allow .mjs content when loaded from file://
diff --git a/LayoutTests/storage/indexeddb/instanceof-iframe-expected.txt b/LayoutTests/storage/indexeddb/instanceof-iframe-expected.txt
new file mode 100644 (file)
index 0000000..55b3d7c
--- /dev/null
@@ -0,0 +1,35 @@
+indexedDB.deleteDatabase('testDB')
+indexedDB.open('testDB', 1)
+openRequest.result.createObjectStore('testObjectStore', {keyPath: 'id'})
+tx = openRequest.result.transaction('testObjectStore', 'readwrite')
+store = tx.objectStore('testObjectStore')
+store.put({id: 1, array:[1,2,3], arrayBuffer: new ArrayBuffer(3), set: new Set([1,2,3]), map: new Map([[1, 'one']]), object: { name: 'test' }})
+store.get(1)
+PASS result.array instanceof Array is true
+PASS result.arrayBuffer instanceof ArrayBuffer is true
+PASS result.set instanceof Set is true
+PASS result.map instanceof Map is true
+PASS result.object instanceof Object is true
+PASS result.array instanceof window.top.Array is true
+PASS result.arrayBuffer instanceof window.top.ArrayBuffer is true
+PASS result.set instanceof window.top.Set is true
+PASS result.map instanceof window.top.Map is true
+PASS result.object instanceof window.top.Object is true
+indexedDB.open('testDB', 1)
+tx = openRequest.result.transaction('testObjectStore', 'readwrite')
+store = tx.objectStore('testObjectStore')
+store.get(1)
+PASS result.array instanceof Array equals to true.
+PASS result.arrayBuffer instanceof ArrayBuffer equals to true.
+PASS result.set instanceof Set equals to true.
+PASS result.map instanceof Map equals to true.
+PASS result.object instanceof Object equals to true.
+PASS result.array instanceof window.top.Array equals to false.
+PASS result.arrayBuffer instanceof window.top.ArrayBuffer equals to false.
+PASS result.set instanceof window.top.Set equals to false.
+PASS result.map instanceof window.top.Map equals to false.
+PASS result.object instanceof window.top.Object equals to false.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/instanceof-iframe.html b/LayoutTests/storage/indexeddb/instanceof-iframe.html
new file mode 100644 (file)
index 0000000..5b53b85
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<script src="../../resources/js-test.js"></script>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<script src="resources/instanceof-iframe.js"></script>
+<iframe id="testIframe"></iframe>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/storage/indexeddb/resources/instanceof-iframe.js b/LayoutTests/storage/indexeddb/resources/instanceof-iframe.js
new file mode 100644 (file)
index 0000000..6317bab
--- /dev/null
@@ -0,0 +1,63 @@
+function test(callback) {
+    isMainFrame = self == top;
+    if (isMainFrame)
+        evalAndLog("indexedDB.deleteDatabase('testDB')");
+    else {
+        shouldBe = function(a, b) {
+            aVal = eval(a);
+            bVal = eval(b);
+            if (aVal != bVal)
+                parent.testFailed(a + " is " + aVal + ", not " + bVal + ".");
+            else 
+                parent.testPassed(a + " equals to " + b  + ".");
+        }
+        shouldBeTrue = function(a) {
+            shouldBe(a, "true");
+        }
+        shouldBeFalse = function(a) {
+            shouldBe(a, "false");
+        }
+        evalAndLog = function(a) {
+            parent.debug(a);
+            return eval(a);
+        }
+    }
+
+    openRequest = evalAndLog("indexedDB.open('testDB', 1)");
+    openRequest.onupgradeneeded = () => { 
+        request = evalAndLog("openRequest.result.createObjectStore('testObjectStore', {keyPath: 'id'})"); 
+        request.onerror = unexpectedErrorCallback;
+    }
+    openRequest.onsuccess = () => {
+        tx = evalAndLog("tx = openRequest.result.transaction('testObjectStore', 'readwrite')");
+        tx.oncomplete = () => { callback(); }
+        store = evalAndLog("store = tx.objectStore('testObjectStore')");
+
+        if (isMainFrame)
+            evalAndLog("store.put({id: 1, array:[1,2,3], arrayBuffer: new ArrayBuffer(3), set: new Set([1,2,3]), map: new Map([[1, 'one']]), object: { name: 'test' }})");
+
+        request = evalAndLog("store.get(1)");
+        request.onsuccess = (event) => {
+            result = request.result;
+
+            shouldBeTrue("result.array instanceof Array");
+            shouldBeTrue("result.arrayBuffer instanceof ArrayBuffer");
+            shouldBeTrue("result.set instanceof Set");
+            shouldBeTrue("result.map instanceof Map");
+            shouldBeTrue("result.object instanceof Object");
+            expected = isMainFrame.toString();
+            shouldBe("result.array instanceof window.top.Array", expected);
+            shouldBe("result.arrayBuffer instanceof window.top.ArrayBuffer", expected);
+            shouldBe("result.set instanceof window.top.Set", expected);
+            shouldBe("result.map instanceof window.top.Map", expected);
+            shouldBe("result.object instanceof window.top.Object", expected);
+        }
+    }
+}
+
+function callback() {
+    iframe = document.getElementById("testIframe");
+    iframe.srcdoc = `<!DOCTYPE html><html></` + `script><script type="text/javascript">${test.toString()} test(function() { parent.finishJSTest();});</` + `script></html>`;
+}
+
+test(callback);
\ No newline at end of file
index 4e5b161..e00d298 100644 (file)
@@ -1,3 +1,19 @@
+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>
+
+        Reviewed by Geoffrey Garen.
+
+        ScriptExecutionContext::execState() returned state of main frame, so deserialization of 
+        IDBValue in iframe used constructors of main frame, which is wrong.
+
+        Test: storage/indexeddb/instanceof-iframe.html
+
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::execState):
+
 2018-11-29  Don Olmstead  <don.olmstead@sony.com>
 
         Make generic ScrollAnimator
index d8f60e2..760dbb6 100644 (file)
@@ -525,7 +525,8 @@ JSC::ExecState* ScriptExecutionContext::execState()
 {
     if (is<Document>(*this)) {
         Document& document = downcast<Document>(*this);
-        return execStateFromPage(mainThreadNormalWorld(), document.page());
+        auto* frame = document.frame();
+        return frame ? frame->script().globalObject(mainThreadNormalWorld())->globalExec() : nullptr;
     }
 
     if (is<WorkerGlobalScope>(*this))