MessageEvent.source window is incorrect once window has been reified
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Apr 2016 01:18:05 +0000 (01:18 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Apr 2016 01:18:05 +0000 (01:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156227
<rdar://problem/25545831>

Reviewed by Mark Lam.

Source/WebCore:

MessageEvent.source window was incorrect once window had been reified.

If the Window had not been reified, we kept constructing new
postMessage() functions when calling window.postMessage(). We used to
pass activeDOMWindow(execState) as source Window to
DOMWindow::postMessage(). activeDOMWindow() uses
exec->lexicalGlobalObject() which did the right thing because we
used to construct a new postMessage() function in the caller's context.

However, after reification, due to the way JSDOMWindow::getOwnPropertySlot()
was implemented, we would stop constructing new postMessage() functions
when calling window.postMessage(). As a result, the source window would
become incorrect because exec->lexicalGlobalObject() would return the
target Window instead.

In this patch, the following is done:
1. Stop constructing a new function every time in the same origin case
   for postMessage, blur, focus and close. This was inefficient and lead
   to incorrect behavior:
   - The behavior would differ depending if the Window is reified or not
   - It would be impossible to delete those operations, which is
     incompatible with the specification and other browsers (tested
     Firefox and Chrome).
2. Use callerDOMWindow(execState) instead of activeDOMWindow(execState)
   as source Window in JSDOMWindow::handlePostMessage(). callerDOMWindow()
   is a new utility function that returns the caller's Window object.

Tests: fast/dom/Window/delete-operations.html
       fast/dom/Window/messageevent-source-postmessage-reified.html
       fast/dom/Window/messageevent-source-postmessage.html
       fast/dom/Window/messageevent-source-postmessage2.html
       fast/dom/Window/window-postmessage-clone-frames.html
       fast/dom/Window/post-message-crash2.html

* bindings/js/JSDOMBinding.cpp:
(WebCore::GetCallerCodeBlockFunctor::operator()):
(WebCore::GetCallerCodeBlockFunctor::codeBlock):
(WebCore::callerDOMWindow):
* bindings/js/JSDOMBinding.h:
* bindings/js/JSDOMWindowCustom.cpp:
(WebCore::handlePostMessage):

LayoutTests:

Add tests that cover using MessageEvent.source Window for messaging
using postMessage(). There are 2 versions of the test, one where the
main window is reified and one where it is not. The test that has a
reified main window was failing because this fix.

* fast/dom/Window/delete-operations-expected.txt: Added.
* fast/dom/Window/delete-operations.html: Added.
Make sure that operations on Window are indeed deletable. Previously,
it would be impossible to delete postMessage, blur, focus and close.

* fast/dom/Window/messageevent-source-postmessage-expected.txt: Added.
* fast/dom/Window/messageevent-source-postmessage-reified-expected.txt: Added.
* fast/dom/Window/messageevent-source-postmessage-reified.html: Added.
* fast/dom/Window/messageevent-source-postmessage.html: Added.
* fast/dom/Window/messageevent-source-postmessage2.html: Added.
* fast/dom/Window/resources/messageevent-source-postmessage-frame.html: Added.
* fast/dom/Window/post-message-crash2-expected.txt: Added.
* fast/dom/Window/post-message-crash2.html: Added.

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

16 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/delete-operations-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/delete-operations.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage2-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/messageevent-source-postmessage2.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/post-message-crash2-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/post-message-crash2.html [new file with mode: 0644]
LayoutTests/fast/dom/Window/resources/messageevent-source-postmessage-frame.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMBinding.h
Source/WebCore/bindings/js/JSDOMWindowCustom.cpp

index 8bff7be..02328ad 100644 (file)
@@ -1,3 +1,30 @@
+2016-04-05  Chris Dumez  <cdumez@apple.com>
+
+        MessageEvent.source window is incorrect once window has been reified
+        https://bugs.webkit.org/show_bug.cgi?id=156227
+        <rdar://problem/25545831>
+
+        Reviewed by Mark Lam.
+
+        Add tests that cover using MessageEvent.source Window for messaging
+        using postMessage(). There are 2 versions of the test, one where the
+        main window is reified and one where it is not. The test that has a
+        reified main window was failing because this fix.
+
+        * fast/dom/Window/delete-operations-expected.txt: Added.
+        * fast/dom/Window/delete-operations.html: Added.
+        Make sure that operations on Window are indeed deletable. Previously,
+        it would be impossible to delete postMessage, blur, focus and close.
+
+        * fast/dom/Window/messageevent-source-postmessage-expected.txt: Added.
+        * fast/dom/Window/messageevent-source-postmessage-reified-expected.txt: Added.
+        * fast/dom/Window/messageevent-source-postmessage-reified.html: Added.
+        * fast/dom/Window/messageevent-source-postmessage.html: Added.
+        * fast/dom/Window/messageevent-source-postmessage2.html: Added.
+        * fast/dom/Window/resources/messageevent-source-postmessage-frame.html: Added.
+        * fast/dom/Window/post-message-crash2-expected.txt: Added.
+        * fast/dom/Window/post-message-crash2.html: Added.
+
 2016-04-05  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Test listbox clipping to contents rect
diff --git a/LayoutTests/fast/dom/Window/delete-operations-expected.txt b/LayoutTests/fast/dom/Window/delete-operations-expected.txt
new file mode 100644 (file)
index 0000000..8d35f08
--- /dev/null
@@ -0,0 +1,75 @@
+Tests deleting window operations works as expected
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.postMessage is an instance of Function
+window.postMessage = 1
+PASS window.postMessage is 1
+PASS delete window.postMessage is true
+PASS window.postMessage is undefined.
+
+PASS window.focus is an instance of Function
+window.focus = 1
+PASS window.focus is 1
+PASS delete window.focus is true
+PASS window.focus is undefined.
+
+PASS window.blur is an instance of Function
+window.blur = 1
+PASS window.blur is 1
+PASS delete window.blur is true
+PASS window.blur is undefined.
+
+PASS window.close is an instance of Function
+window.close = 1
+PASS window.close is 1
+PASS delete window.close is true
+PASS window.close is undefined.
+
+PASS window.open is an instance of Function
+window.open = 1
+PASS window.open is 1
+PASS delete window.open is true
+PASS window.open is undefined.
+
+PASS window.showModalDialog is an instance of Function
+window.showModalDialog = 1
+PASS window.showModalDialog is 1
+PASS delete window.showModalDialog is true
+PASS window.showModalDialog is undefined.
+
+PASS window.alert is an instance of Function
+window.alert = 1
+PASS window.alert is 1
+PASS delete window.alert is true
+PASS window.alert is undefined.
+
+PASS window.confirm is an instance of Function
+window.confirm = 1
+PASS window.confirm is 1
+PASS delete window.confirm is true
+PASS window.confirm is undefined.
+
+PASS window.prompt is an instance of Function
+window.prompt = 1
+PASS window.prompt is 1
+PASS delete window.prompt is true
+PASS window.prompt is undefined.
+
+PASS window.stop is an instance of Function
+window.stop = 1
+PASS window.stop is 1
+PASS delete window.stop is true
+PASS window.stop is undefined.
+
+PASS window.scroll is an instance of Function
+window.scroll = 1
+PASS window.scroll is 1
+PASS delete window.scroll is true
+PASS window.scroll is undefined.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Window/delete-operations.html b/LayoutTests/fast/dom/Window/delete-operations.html
new file mode 100644 (file)
index 0000000..3a757e0
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<body>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+description("Tests deleting window operations works as expected");
+
+function testFunction(functionName)
+{
+    shouldBeType("window." + functionName, "Function");
+    evalAndLog("window." + functionName + " = 1");
+    shouldBe("window." + functionName, "1");
+    shouldBeTrue("delete window." + functionName);
+    shouldBeUndefined("window." + functionName);
+    debug("");
+}
+
+testFunction("postMessage");
+testFunction("focus");
+testFunction("blur");
+testFunction("close");
+testFunction("open");
+testFunction("showModalDialog");
+testFunction("alert");
+testFunction("confirm");
+testFunction("prompt");
+testFunction("stop");
+testFunction("scroll");
+
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage-expected.txt b/LayoutTests/fast/dom/Window/messageevent-source-postmessage-expected.txt
new file mode 100644 (file)
index 0000000..a6db670
--- /dev/null
@@ -0,0 +1,35 @@
+Tests that MessageEvent.source is correct and can be used for messaging.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* Sending message 1 to child
+* Parent received message 2 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+* Sending message 3 to child
+* Parent received message 4 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+* Sending message 5 to child
+* Parent received message 6 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+* Child received message 1 from parent
+PASS messageEvent.source is parent
+* Sending message 2 to parent
+* Child received message 3 from parent
+PASS messageEvent.source is parent
+* Sending message 4 to parent
+* Child received message 5 from parent
+PASS messageEvent.source is parent
+* Sending message 6 to parent
+
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified-expected.txt b/LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified-expected.txt
new file mode 100644 (file)
index 0000000..b7bbcfd
--- /dev/null
@@ -0,0 +1,35 @@
+Tests that MessageEvent.source is correct and can be used for messaging (reified Window case).
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* Sending message 1 to child
+* Parent received message 2 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+* Sending message 3 to child
+* Parent received message 4 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+* Sending message 5 to child
+* Parent received message 6 from child
+PASS messageEvent.source is frames[0]
+PASS messageEvent.data is counter + 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+* Child received message 1 from parent
+PASS messageEvent.source is parent
+* Sending message 2 to parent
+* Child received message 3 from parent
+PASS messageEvent.source is parent
+* Sending message 4 to parent
+* Child received message 5 from parent
+PASS messageEvent.source is parent
+* Sending message 6 to parent
+
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified.html b/LayoutTests/fast/dom/Window/messageevent-source-postmessage-reified.html
new file mode 100644 (file)
index 0000000..a789113
--- /dev/null
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<script src="../../../resources/js-test-pre.js"></script>
+<body onload="runTest()">
+<script>
+description("Tests that MessageEvent.source is correct and can be used for messaging (reified Window case).");
+jsTestIsAsync = true;
+
+// Reify the window.
+window.test = 1;
+delete window.test;
+
+if (window.testRunner)
+    testRunner.dumpChildFramesAsText();
+
+counter = 1;
+
+window.onmessage = function(e) {
+    debug("* Parent received message " + e.data + " from child");
+    messageEvent = e;
+    shouldBe("messageEvent.source", "frames[0]");
+    shouldBe("messageEvent.data", "counter + 1");
+    if (messageEvent.data > 5) {
+        finishJSTest();
+        return;
+    }
+    counter = messageEvent.data + 1;
+    debug("* Sending message " + counter + " to child");
+    messageEvent.source.postMessage(counter, "*");
+}
+
+function runTest()
+{
+    debug("* Sending message " + counter + " to child");
+    frames[0].postMessage(counter, "*");
+}
+
+</script>
+<iframe src="resources/messageevent-source-postmessage-frame.html"></iframe>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage.html b/LayoutTests/fast/dom/Window/messageevent-source-postmessage.html
new file mode 100644 (file)
index 0000000..9867310
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<script src="../../../resources/js-test-pre.js"></script>
+<body onload="runTest()">
+<script>
+description("Tests that MessageEvent.source is correct and can be used for messaging.");
+jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.dumpChildFramesAsText();
+
+counter = 1;
+
+window.onmessage = function(e) {
+    debug("* Parent received message " + e.data + " from child");
+    messageEvent = e;
+    shouldBe("messageEvent.source", "frames[0]");
+    shouldBe("messageEvent.data", "counter + 1");
+    if (messageEvent.data > 5) {
+        finishJSTest();
+        return;
+    }
+    counter = messageEvent.data + 1;
+    debug("* Sending message " + counter + " to child");
+    messageEvent.source.postMessage(counter, "*");
+}
+
+function runTest()
+{
+    debug("* Sending message " + counter + " to child");
+    frames[0].postMessage(counter, "*");
+}
+
+</script>
+<iframe src="resources/messageevent-source-postmessage-frame.html"></iframe>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage2-expected.txt b/LayoutTests/fast/dom/Window/messageevent-source-postmessage2-expected.txt
new file mode 100644 (file)
index 0000000..5efab1c
--- /dev/null
@@ -0,0 +1,11 @@
+Checks that MessageEvent.source window is correct when postMessage() is called cross-frame via a function in the other frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS messageEvent.data is "msg"
+PASS messageEvent.source is frames[0]
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Window/messageevent-source-postmessage2.html b/LayoutTests/fast/dom/Window/messageevent-source-postmessage2.html
new file mode 100644 (file)
index 0000000..6e1ecbd
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<body>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+description("Checks that MessageEvent.source window is correct when postMessage() is called cross-frame via a function in the other frame.");
+jsTestIsAsync = true;
+
+window.onmessage = function(e) {
+    messageEvent = e;
+    shouldBeEqualToString("messageEvent.data", "msg");
+    shouldBe("messageEvent.source", "frames[0]");
+    finishJSTest();
+}
+
+onload = function()
+{
+    frames[0].sendMessage();
+}
+</script>
+<iframe srcdoc="<script>function sendMessage() { parent.postMessage('msg', '*'); }</script>"></iframe>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
diff --git a/LayoutTests/fast/dom/Window/post-message-crash2-expected.txt b/LayoutTests/fast/dom/Window/post-message-crash2-expected.txt
new file mode 100644 (file)
index 0000000..3e28a90
--- /dev/null
@@ -0,0 +1,11 @@
+This ensures that postMessage called in a callback does not crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS messageEvent.data is "msg"
+PASS messageEvent.source is window
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/Window/post-message-crash2.html b/LayoutTests/fast/dom/Window/post-message-crash2.html
new file mode 100644 (file)
index 0000000..aad5b24
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src="../../../resources/js-test-pre.js"></script>
+<script>
+description("This ensures that postMessage called in a callback does not crash.");
+jsTestIsAsync = true;
+
+window.onmessage = function(e) {
+   messageEvent = e;
+   shouldBeEqualToString("messageEvent.data", "msg");
+   shouldBe("messageEvent.source", "window");
+   finishJSTest();
+}
+
+var boundPostMessage = window.postMessage.bind(window, "msg", "*");
+setTimeout(boundPostMessage, 0);
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/Window/resources/messageevent-source-postmessage-frame.html b/LayoutTests/fast/dom/Window/resources/messageevent-source-postmessage-frame.html
new file mode 100644 (file)
index 0000000..246dc3d
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<body>
+<script src="../../../../resources/js-test-pre.js"></script>
+<script>
+jsTestIsAsync = true;
+
+window.onmessage = function(e) {
+    debug("* Child received message " + e.data + " from parent");
+    messageEvent = e;
+    shouldBe("messageEvent.source", "parent");
+    debug("* Sending message " + (e.data + 1) + " to parent");
+    messageEvent.source.postMessage(e.data + 1, "*");
+}
+</script>
+<script src="../../../../resources/js-test-post.js"></script>
+</body>
index 7fd9a1c..317cc72 100644 (file)
@@ -1,3 +1,53 @@
+2016-04-05  Chris Dumez  <cdumez@apple.com>
+
+        MessageEvent.source window is incorrect once window has been reified
+        https://bugs.webkit.org/show_bug.cgi?id=156227
+        <rdar://problem/25545831>
+
+        Reviewed by Mark Lam.
+
+        MessageEvent.source window was incorrect once window had been reified.
+
+        If the Window had not been reified, we kept constructing new
+        postMessage() functions when calling window.postMessage(). We used to
+        pass activeDOMWindow(execState) as source Window to
+        DOMWindow::postMessage(). activeDOMWindow() uses
+        exec->lexicalGlobalObject() which did the right thing because we
+        used to construct a new postMessage() function in the caller's context.
+
+        However, after reification, due to the way JSDOMWindow::getOwnPropertySlot()
+        was implemented, we would stop constructing new postMessage() functions
+        when calling window.postMessage(). As a result, the source window would
+        become incorrect because exec->lexicalGlobalObject() would return the
+        target Window instead.
+
+        In this patch, the following is done:
+        1. Stop constructing a new function every time in the same origin case
+           for postMessage, blur, focus and close. This was inefficient and lead
+           to incorrect behavior:
+           - The behavior would differ depending if the Window is reified or not
+           - It would be impossible to delete those operations, which is
+             incompatible with the specification and other browsers (tested
+             Firefox and Chrome).
+        2. Use callerDOMWindow(execState) instead of activeDOMWindow(execState)
+           as source Window in JSDOMWindow::handlePostMessage(). callerDOMWindow()
+           is a new utility function that returns the caller's Window object.
+
+        Tests: fast/dom/Window/delete-operations.html
+               fast/dom/Window/messageevent-source-postmessage-reified.html
+               fast/dom/Window/messageevent-source-postmessage.html
+               fast/dom/Window/messageevent-source-postmessage2.html
+               fast/dom/Window/window-postmessage-clone-frames.html
+               fast/dom/Window/post-message-crash2.html
+
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::GetCallerCodeBlockFunctor::operator()):
+        (WebCore::GetCallerCodeBlockFunctor::codeBlock):
+        (WebCore::callerDOMWindow):
+        * bindings/js/JSDOMBinding.h:
+        * bindings/js/JSDOMWindowCustom.cpp:
+        (WebCore::handlePostMessage):
+
 2016-04-05  Beth Dakin  <bdakin@apple.com>
 
         Make requestCandidatesForSelection available on any EditorClient
index 20b9ff5..3cb2a55 100644 (file)
@@ -35,6 +35,7 @@
 #include "JSDOMWindowCustom.h"
 #include "JSExceptionBase.h"
 #include "SecurityOrigin.h"
+#include <bytecode/CodeBlock.h>
 #include <inspector/ScriptCallStack.h>
 #include <inspector/ScriptCallStackFactory.h>
 #include <interpreter/Interpreter.h>
@@ -557,6 +558,40 @@ uint64_t toUInt64(ExecState* exec, JSValue value, IntegerConversionConfiguration
     return n;
 }
 
+class GetCallerGlobalObjectFunctor {
+public:
+    GetCallerGlobalObjectFunctor() = default;
+
+    StackVisitor::Status operator()(StackVisitor& visitor) const
+    {
+        if (!m_hasSkippedFirstFrame) {
+            m_hasSkippedFirstFrame = true;
+            return StackVisitor::Continue;
+        }
+
+        if (auto* codeBlock = visitor->codeBlock())
+            m_globalObject = codeBlock->globalObject();
+        else {
+            ASSERT(visitor->callee());
+            m_globalObject = visitor->callee()->globalObject();
+        }
+        return StackVisitor::Done;
+    }
+
+    JSGlobalObject* globalObject() const { return m_globalObject; }
+
+private:
+    mutable bool m_hasSkippedFirstFrame { false };
+    mutable JSGlobalObject* m_globalObject { nullptr };
+};
+
+DOMWindow& callerDOMWindow(ExecState* exec)
+{
+    GetCallerGlobalObjectFunctor iter;
+    exec->iterate(iter);
+    return iter.globalObject() ? asJSDOMWindow(iter.globalObject())->wrapped() : firstDOMWindow(exec);
+}
+
 DOMWindow& activeDOMWindow(ExecState* exec)
 {
     return asJSDOMWindow(exec->lexicalGlobalObject())->wrapped();
index c8902e6..758741f 100644 (file)
@@ -78,6 +78,7 @@ struct ExceptionDetails {
 
 typedef int ExceptionCode;
 
+DOMWindow& callerDOMWindow(JSC::ExecState*);
 DOMWindow& activeDOMWindow(JSC::ExecState*);
 DOMWindow& firstDOMWindow(JSC::ExecState*);
 
index 5b5da95..3b26dfd 100644 (file)
@@ -237,30 +237,6 @@ bool JSDOMWindow::getOwnPropertySlot(JSObject* object, ExecState* exec, Property
     // (Particularly, is it correct that this exists here but not in getOwnPropertySlotByIndex?)
     slot.setWatchpointSet(thisObject->m_windowCloseWatchpoints);
 
-    // FIXME: These are all bogus. Keeping these here make some tests pass that check these properties
-    // are own properties of the window, but introduces other problems instead (e.g. if you overwrite
-    // & delete then the original value is restored!) Should be removed.
-    if (propertyName == exec->propertyNames().blur) {
-        if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowInstanceFunctionBlur, 0>);
-        return true;
-    }
-    if (propertyName == exec->propertyNames().close) {
-        if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowInstanceFunctionClose, 0>);
-        return true;
-    }
-    if (propertyName == exec->propertyNames().focus) {
-        if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowInstanceFunctionFocus, 0>);
-        return true;
-    }
-    if (propertyName == exec->propertyNames().postMessage) {
-        if (!Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
-            slot.setCustom(thisObject, ReadOnly | DontDelete | DontEnum, nonCachingStaticFunctionGetter<jsDOMWindowInstanceFunctionPostMessage, 2>);
-        return true;
-    }
-
     if (propertyName == exec->propertyNames().showModalDialog) {
         if (Base::getOwnPropertySlot(thisObject, exec, propertyName, slot))
             return true;
@@ -588,7 +564,7 @@ static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
         return jsUndefined();
 
     ExceptionCode ec = 0;
-    impl.postMessage(message.release(), &messagePorts, targetOrigin, activeDOMWindow(&state), ec);
+    impl.postMessage(message.release(), &messagePorts, targetOrigin, callerDOMWindow(&state), ec);
     setDOMException(&state, ec);
 
     return jsUndefined();