WebCore:
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2008 22:00:05 +0000 (22:00 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2008 22:00:05 +0000 (22:00 +0000)
2008-05-06  Adam Barth  <abarth-webkit@adambarth.com>

        Reviewed by Sam Weinig.

        https://bugs.webkit.org/show_bug.cgi?id=18725
        Implement asynchronous postMessage.
        MessageEvent no longer bubbles as per r1237 in the HTML 5 working draft.

        Collin Jackson <collinj-webkit@collinjackson.com> also contributed to this patch.

        Test: http/tests/security/postMessage/delivery-order.html

        * dom/MessageEvent.cpp:
        (WebCore::MessageEvent::MessageEvent):
        * page/DOMWindow.cpp:
        (WebCore::PostMessageTimer::PostMessageTimer):
        (WebCore::PostMessageTimer::event):
        (WebCore::PostMessageTimer::targetOrigin):
        (WebCore::PostMessageTimer::fired):
        (WebCore::DOMWindow::postMessage):
        (WebCore::DOMWindow::postMessageTimerFired):
        * page/DOMWindow.h:
        * page/DOMWindow.idl:

LayoutTests:

2008-05-06  Adam Barth  <abarth-webkit@adambarth.com>

        Reviewed by Sam Weinig.

        https://bugs.webkit.org/show_bug.cgi?id=18725
        Update tests for asynchronous postMessage.

        Collin Jackson <collinj-webkit@collinjackson.com> also contributed to this patch.

        * http/tests/messaging/cross-domain-message-send.html:
        * http/tests/messaging/resources/cross-domain-message-receive.html:
        * http/tests/security/cross-frame-access-delete.html:
        * http/tests/security/cross-frame-access-history-put.html:
        * http/tests/security/cross-frame-access-location-put.html:
        * http/tests/security/postMessage/delivery-order-expected.txt: Added.
        * http/tests/security/postMessage/delivery-order.html: Added.
        * http/tests/security/postMessage/invalid-origin-throws-exception-expected.txt:
        * http/tests/security/postMessage/invalid-origin-throws-exception.html:
        * http/tests/security/postMessage/origin-unaffected-by-base-tag-expected.txt:
        * http/tests/security/postMessage/origin-unaffected-by-base-tag.html:
        * http/tests/security/postMessage/origin-unaffected-by-document-domain-expected.txt:
        * http/tests/security/postMessage/origin-unaffected-by-document-domain.html:
        * http/tests/security/postMessage/resources/javascript-post-message-sender.html:
        * http/tests/security/postMessage/resources/post-message-listener.html:
        * http/tests/security/postMessage/resources/recv.js: Added.
        * http/tests/security/postMessage/target-origin-expected.txt:
        * http/tests/security/postMessage/target-origin.html:
        * http/tests/security/resources/cross-frame-iframe-for-delete-test.html:
        * http/tests/security/resources/cross-frame-iframe-for-history-put-test.html:
        * http/tests/security/resources/cross-frame-iframe-for-location-put-test.html:
        * http/tests/security/resources/xss-eval3.html:
        * http/tests/security/xss-eval.html:

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/messaging/cross-domain-message-send.html
LayoutTests/http/tests/messaging/resources/cross-domain-message-receive.html
LayoutTests/http/tests/security/cross-frame-access-delete.html
LayoutTests/http/tests/security/cross-frame-access-history-put.html
LayoutTests/http/tests/security/cross-frame-access-location-put.html
LayoutTests/http/tests/security/postMessage/delivery-order-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/postMessage/delivery-order.html [new file with mode: 0644]
LayoutTests/http/tests/security/postMessage/invalid-origin-throws-exception-expected.txt
LayoutTests/http/tests/security/postMessage/invalid-origin-throws-exception.html
LayoutTests/http/tests/security/postMessage/origin-unaffected-by-base-tag-expected.txt
LayoutTests/http/tests/security/postMessage/origin-unaffected-by-base-tag.html
LayoutTests/http/tests/security/postMessage/origin-unaffected-by-document-domain-expected.txt
LayoutTests/http/tests/security/postMessage/origin-unaffected-by-document-domain.html
LayoutTests/http/tests/security/postMessage/resources/javascript-post-message-sender.html
LayoutTests/http/tests/security/postMessage/resources/post-message-listener.html
LayoutTests/http/tests/security/postMessage/resources/recv.js [new file with mode: 0644]
LayoutTests/http/tests/security/postMessage/target-origin-expected.txt
LayoutTests/http/tests/security/postMessage/target-origin.html
LayoutTests/http/tests/security/resources/cross-frame-iframe-for-delete-test.html
LayoutTests/http/tests/security/resources/cross-frame-iframe-for-history-put-test.html
LayoutTests/http/tests/security/resources/cross-frame-iframe-for-location-put-test.html
LayoutTests/http/tests/security/resources/xss-eval2.html
LayoutTests/http/tests/security/resources/xss-eval3.html
LayoutTests/http/tests/security/xss-eval.html
WebCore/ChangeLog
WebCore/dom/MessageEvent.cpp
WebCore/page/DOMWindow.cpp
WebCore/page/DOMWindow.h
WebCore/page/DOMWindow.idl

index 809e58e..979744a 100644 (file)
@@ -1,3 +1,36 @@
+2008-05-06  Adam Barth  <abarth-webkit@adambarth.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=18725
+        Update tests for asynchronous postMessage.
+
+        Collin Jackson <collinj-webkit@collinjackson.com> also contributed to this patch.
+
+        * http/tests/messaging/cross-domain-message-send.html:
+        * http/tests/messaging/resources/cross-domain-message-receive.html:
+        * http/tests/security/cross-frame-access-delete.html:
+        * http/tests/security/cross-frame-access-history-put.html:
+        * http/tests/security/cross-frame-access-location-put.html:
+        * http/tests/security/postMessage/delivery-order-expected.txt: Added.
+        * http/tests/security/postMessage/delivery-order.html: Added.
+        * http/tests/security/postMessage/invalid-origin-throws-exception-expected.txt:
+        * http/tests/security/postMessage/invalid-origin-throws-exception.html:
+        * http/tests/security/postMessage/origin-unaffected-by-base-tag-expected.txt:
+        * http/tests/security/postMessage/origin-unaffected-by-base-tag.html:
+        * http/tests/security/postMessage/origin-unaffected-by-document-domain-expected.txt:
+        * http/tests/security/postMessage/origin-unaffected-by-document-domain.html:
+        * http/tests/security/postMessage/resources/javascript-post-message-sender.html:
+        * http/tests/security/postMessage/resources/post-message-listener.html:
+        * http/tests/security/postMessage/resources/recv.js: Added.
+        * http/tests/security/postMessage/target-origin-expected.txt:
+        * http/tests/security/postMessage/target-origin.html:
+        * http/tests/security/resources/cross-frame-iframe-for-delete-test.html:
+        * http/tests/security/resources/cross-frame-iframe-for-history-put-test.html:
+        * http/tests/security/resources/cross-frame-iframe-for-location-put-test.html:
+        * http/tests/security/resources/xss-eval3.html:
+        * http/tests/security/xss-eval.html:
+
 2008-05-05  Alexey Proskuryakov  <ap@webkit.org>
 
         Reviewed by Darin.
index cc541e2..8c19cbc 100644 (file)
@@ -12,7 +12,7 @@ if (window.layoutTestController) {
 }
 
 function postIt () {
-    document.getElementById("receiver").contentWindow.postMessage("Something");
+    document.getElementById("receiver").contentWindow.postMessage("Something", "*");
 }
 
 function receiver(e) {
index defb573..a8c9ed5 100644 (file)
@@ -10,7 +10,7 @@ function receiver(e) {
     var result = "";
     result += "data: " + e.data + "\n";
     result += "origin: " + e.origin + "\n";
-    e.source.postMessage(result);   
+    e.source.postMessage(result, "*");   
 }
 
 document.addEventListener('message', receiver, false);
index d8c1cc4..dbaaeb1 100644 (file)
@@ -26,7 +26,7 @@
             shouldBe("eval('delete targetWindow.location.existingProperty')", "false");
             shouldBe("eval('delete targetWindow.location[1]')", "false");
 
-            targetWindow.postMessage("deletingValuesComplete");
+            targetWindow.postMessage("deletingValuesComplete", "*");
         }
     </script>
 </head>
index f5f763f..b6f3739 100644 (file)
@@ -43,7 +43,7 @@
             try { targetWindow.history.customAttribute = "FAIL!! CUSTOM customAttribute"; } catch(e) { log(e); }
 
             if (window.postMessage)
-                targetWindow.postMessage("settingValuesComplete");
+                targetWindow.postMessage("settingValuesComplete", "*");
             else
                 log("\nSet Test complete!  Click button entitled 'Step 2 - Set Check' to finish the test.");
         }
index fcfe9a8..1a02bc8 100644 (file)
@@ -44,7 +44,7 @@
             try { targetWindow.location.customAttribute = "FAIL!! CUSTOM customAttribute"; } catch(e) { log(e); }
 
             if (window.postMessage)
-                targetWindow.postMessage("settingValuesComplete");
+                targetWindow.postMessage("settingValuesComplete", "*");
             else
                 log("\nSet Test complete!  Click button entitled 'Step 2 - Set Check' to finish the test.");
         }
diff --git a/LayoutTests/http/tests/security/postMessage/delivery-order-expected.txt b/LayoutTests/http/tests/security/postMessage/delivery-order-expected.txt
new file mode 100644 (file)
index 0000000..bb2b7b9
--- /dev/null
@@ -0,0 +1,7 @@
+window.location.href = http://127.0.0.1:8000/security/postMessage/delivery-order.html
+
+waiting...
+Before calling postMessage
+After calling postMessage
+Received message: data="Received message: data="Message from parent" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="done" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
diff --git a/LayoutTests/http/tests/security/postMessage/delivery-order.html b/LayoutTests/http/tests/security/postMessage/delivery-order.html
new file mode 100644 (file)
index 0000000..d01d6dc
--- /dev/null
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="resources/recv.js"></script>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+document.addEventListener('message', recv, false);
+
+function test() {
+    var iframe = document.getElementById('child');
+    var win = iframe.contentWindow;
+
+    log('Before calling postMessage');
+    win.postMessage('Message from parent', '*');
+    log('After calling postMessage');
+
+    win.postMessage('done', '*');
+}
+</script>
+<base href="http://www.example.com/">
+<body>
+<div>window.location.href = <script>document.write(document.location.href);</script></div>
+<div><iframe src="http://localhost:8000/security/postMessage/resources/post-message-listener.html" onload="test()"
+  id="child" width="800" height="300" style="border: 1px solid black;">
+</iframe></div>
+<div id="result">waiting...</div>
+</body>
+</html>
+
index 00b17ff..818e572 100644 (file)
@@ -1,10 +1,10 @@
-CONSOLE MESSAGE: line 0: Unable to post message to asdf:. Recipient has origin http://localhost:8000.
+CONSOLE MESSAGE: line 0: Unable to post message to asdf://. Recipient has origin http://localhost:8000.
 
-CONSOLE MESSAGE: line 0: Unable to post message to http:. Recipient has origin http://localhost:8000.
+CONSOLE MESSAGE: line 0: Unable to post message to http://. Recipient has origin http://localhost:8000.
 
-CONSOLE MESSAGE: line 0: Unable to post message to /tmp/foo. Recipient has origin http://localhost:8000.
+CONSOLE MESSAGE: line 0: Unable to post message to localhost:8000.
 
-CONSOLE MESSAGE: line 0: Unable to post message to //localhost. Recipient has origin http://localhost:8000.
+CONSOLE MESSAGE: line 0: Unable to post message to localhost:8000.
 
 window.location.href = http://127.0.0.1:8000/security/postMessage/invalid-origin-throws-exception.html
 
@@ -15,3 +15,4 @@ Posted message to 'asdf:' without any exceptions.
 Posted message to 'http:' without any exceptions.
 Posted message to '/tmp/foo' without any exceptions.
 Posted message to '//localhost' without any exceptions.
+Received message: data="Received message: data="done" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
index 575c530..c2b68f3 100644 (file)
@@ -1,20 +1,12 @@
-<script>
-if (window.layoutTestController)
-  layoutTestController.dumpAsText();
-</script>
-
 <!DOCTYPE html>
 <html>
 <head>
+<script src="resources/recv.js"></script>
 <script>
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
 }
-
-function recv(e) {
-    document.getElementById("result").innerHTML += "<br>" + e.data;
-}
  
 document.addEventListener("message", recv, false);
 
@@ -43,8 +35,8 @@ function test() {
     tryPostMessage("/tmp/foo");
     tryPostMessage("//localhost");
 
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
+    
+    win.postMessage('done', '*');
 }
 </script>
 <body>
index 3d6e990..64e357b 100644 (file)
@@ -1,3 +1,5 @@
 window.location.href = http://127.0.0.1:8000/security/postMessage/origin-unaffected-by-base-tag.html
 
-Received message: data="Message from parent" origin="http://127.0.0.1:8000"
+waiting...
+Received message: data="Received message: data="Message from parent" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="done" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
index a230af0..b163829 100644 (file)
@@ -1,25 +1,21 @@
 <!DOCTYPE html>
 <html>
 <head>
+<script src="resources/recv.js"></script>
 <script>
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
 }
 
-function recv(e) {
-    document.getElementById("result").firstChild.data = e.data;
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
 document.addEventListener("message", recv, false);
 
 function test() {
     var iframe = document.getElementById('child');
     var win = iframe.contentWindow;
-    win.postMessage('Message from parent');
+    win.postMessage('Message from parent', '*');
+
+    win.postMessage('done', '*');
 }
 </script>
 <base href="http://www.example.com/">
index 23e4c67..f89537f 100644 (file)
@@ -1,4 +1,6 @@
 window.location.href = http://127.0.0.1:8000/security/postMessage/origin-unaffected-by-document-domain.html
 document.domain = 0.0.1
 
-Received message: data="Message from parent" origin="http://127.0.0.1:8000"
+waiting...
+Received message: data="Received message: data="Message from parent" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="done" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
index d389c9e..308c143 100644 (file)
@@ -1,25 +1,21 @@
 <!DOCTYPE html>
 <html>
 <head>
+<script src="resources/recv.js"></script>
 <script>
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
 }
 
-function recv(e) {
-    document.getElementById("result").firstChild.data = e.data;
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
 document.addEventListener("message", recv, false);
 
 function test() {
     var iframe = document.getElementById('child');
     var win = iframe.contentWindow;
-    win.postMessage('Message from parent');
+    win.postMessage('Message from parent', '*');
+
+    win.postMessage('done', '*');
 }
 
 document.domain = "0.0.1";
index ff00e1f..0cece09 100644 (file)
@@ -4,7 +4,7 @@
 <script>
 function nav() {
     var url = "javascript:'<script>" + 
-      "top.postMessage(\"Hello from child\");" + 
+      "top.postMessage(\"Hello from child\", \"*\");" + 
       "document.write(\"Message sent\");" +
       "</scri" + "pt>'";
 
index 6a2ca94..c93760e 100644 (file)
@@ -5,7 +5,7 @@
 <script>
 function recv(e) {
     var msg = 'Received message: data="' + e.data + '" origin="' + e.origin + '"';
-    top.postMessage(msg);
+    top.postMessage(msg, '*');
 }
 
 document.addEventListener("message", recv, false);
diff --git a/LayoutTests/http/tests/security/postMessage/resources/recv.js b/LayoutTests/http/tests/security/postMessage/resources/recv.js
new file mode 100644 (file)
index 0000000..ed31bcb
--- /dev/null
@@ -0,0 +1,15 @@
+function log(msg) {
+    var div = document.createElement('div');
+    div.appendChild(document.createTextNode(msg));
+    document.getElementById('result').appendChild(div);
+}
+
+function recv(e) {
+    var msg = 'Received message: data="' + e.data + '" origin="' + e.origin + '"';
+
+    log(msg);
+
+    if (e.data.match(/data="done"/) && window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
index 64b05c4..464c1fc 100644 (file)
@@ -11,11 +11,13 @@ CONSOLE MESSAGE: line 0: Unable to post message to http://www.example.com. Recip
 window.location.href = http://127.0.0.1:8000/security/postMessage/target-origin.html
 
 waiting...
-Received message: data="Trying origin=http://localhost:8000" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=http://localhost:8000/" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=http://localhost:8000/foo" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=http://localhost:8000/foo?bar" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=http://localhost:8000/foo?bar#baz" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=http://user:pass@localhost:8000/foo?bar#baz" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=null" origin="http://127.0.0.1:8000"
-Received message: data="Trying origin=undefined" origin="http://127.0.0.1:8000"
+Error sending message to null. Error: SYNTAX_ERR: DOM Exception 12
+Error sending message to undefined. Error: SYNTAX_ERR: DOM Exception 12
+Received message: data="Received message: data="Trying origin=http://localhost:8000" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=http://localhost:8000/" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=http://localhost:8000/foo" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=http://localhost:8000/foo?bar" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=http://localhost:8000/foo?bar#baz" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=http://user:pass@localhost:8000/foo?bar#baz" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="Trying origin=*" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
+Received message: data="Received message: data="done" origin="http://127.0.0.1:8000"" origin="http://localhost:8000"
index c937c14..b7d0a44 100644 (file)
@@ -1,20 +1,21 @@
 <!DOCTYPE html>
 <html>
 <head>
+<script src="resources/recv.js"></script>
 <script>
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
 }
 
-function recv(e) {
-    document.getElementById("result").innerHTML += "<br>" + e.data;
-}
 document.addEventListener("message", recv, false);
 
 function tryPostMessage(win, origin) {
-    win.postMessage("Trying origin=" + origin, origin);
+    try {
+        win.postMessage("Trying origin=" + origin, origin);
+    } catch(ex) {
+        log("Error sending message to " + origin + ". " + ex);
+    }
 }
 
 function test() {
@@ -28,8 +29,7 @@ function test() {
     tryPostMessage(win, "http://localhost:8000/foo?bar");
     tryPostMessage(win, "http://localhost:8000/foo?bar#baz");
     tryPostMessage(win, "http://user:pass@localhost:8000/foo?bar#baz");
-    tryPostMessage(win, null);
-    tryPostMessage(win, undefined);
+    tryPostMessage(win, "*");
 
     // Should fail:
     tryPostMessage(win, "http://localhost:9090");
@@ -38,8 +38,11 @@ function test() {
     tryPostMessage(win, "https://localhost:8000");
     tryPostMessage(win, "http://www.example.com");
 
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
+    // Should throw syntax error:
+    tryPostMessage(win, null);
+    tryPostMessage(win, undefined);
+
+    win.postMessage('done', '*');
 }
 </script>
 <body>
index e34f6f4..e754a4f 100644 (file)
@@ -18,7 +18,7 @@
             window.location.existingProperty = "test value";
             window.location[1] = "test value";
 
-            window.parent.postMessage("setValuesComplete");
+            window.parent.postMessage("setValuesComplete", "*");
         }
 
         setCheck = function()
index ff527cb..dcb4f17 100644 (file)
@@ -36,7 +36,7 @@
             customAttributeOld = window.history.customAttribute;
 
             if (window.postMessage)
-                window.parent.postMessage("storedOldValuesComplete");
+                window.parent.postMessage("storedOldValuesComplete", "*");
         }
 
         setCheck = function()
index 10f3e63..aa97aec 100644 (file)
@@ -34,7 +34,7 @@
             customAttributeOld = window.location.customAttribute;
 
             if (window.postMessage)
-                window.parent.postMessage("storedOldValuesComplete");
+                window.parent.postMessage("storedOldValuesComplete", "*");
         }
 
         setCheck = function()
index 7e67b3a..dea2e5a 100644 (file)
@@ -2,7 +2,7 @@
 parent.childEval = eval;
 
 parent.childEvalCaller = function(s) {
-    return eval(s);
+    return window.eval(s);
 }
 
 parent.childLocalEvalCaller = (function()
index 5627282..96dc2ea 100644 (file)
@@ -25,7 +25,7 @@ function shouldBe(aDescription, a, b)
     }
 }
 
-addEventListener("message", function()
+document.addEventListener("message", function()
 {
     shouldBe("eval.call(frames[0], 'document')", (function() { try { return eval.call(frames[0], 'document'); } catch(e) { return e.name; } })(), "EvalError");
 
index f3bfe11..a1109b5 100644 (file)
@@ -1,3 +1,27 @@
+2008-05-06  Adam Barth  <abarth-webkit@adambarth.com>
+
+        Reviewed by Sam Weinig.
+
+        https://bugs.webkit.org/show_bug.cgi?id=18725
+        Implement asynchronous postMessage.
+        MessageEvent no longer bubbles as per r1237 in the HTML 5 working draft.
+
+        Collin Jackson <collinj-webkit@collinjackson.com> also contributed to this patch.
+
+        Test: http/tests/security/postMessage/delivery-order.html
+
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEvent::MessageEvent):
+        * page/DOMWindow.cpp:
+        (WebCore::PostMessageTimer::PostMessageTimer):
+        (WebCore::PostMessageTimer::event):
+        (WebCore::PostMessageTimer::targetOrigin):
+        (WebCore::PostMessageTimer::fired):
+        (WebCore::DOMWindow::postMessage):
+        (WebCore::DOMWindow::postMessageTimerFired):
+        * page/DOMWindow.h:
+        * page/DOMWindow.idl:
+        
 2008-05-06  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Brady.
index b11187f..a74dd23 100644 (file)
@@ -42,7 +42,7 @@ MessageEvent::MessageEvent()
 }
 
 MessageEvent::MessageEvent(const String& data, const String& origin, DOMWindow* source)
-    : Event(messageEvent, true, true)
+    : Event(messageEvent, false, true)
     , m_data(data)
     , m_origin(origin)
     , m_source(source)
index 87bb6ab..995eb1a 100644 (file)
@@ -79,6 +79,31 @@ using std::max;
 
 namespace WebCore {
 
+#if ENABLE(CROSS_DOCUMENT_MESSAGING)
+class PostMessageTimer : public TimerBase {
+public:
+    PostMessageTimer(DOMWindow* window, MessageEvent* event, SecurityOrigin* targetOrigin)
+        : m_window(window)
+        , m_event(event)
+        , m_targetOrigin(targetOrigin)
+    {
+    }
+
+    MessageEvent* event() const { return m_event.get(); }
+    SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
+
+private:
+    virtual void fired() 
+    {
+        m_window->postMessageTimerFired(this);
+    }
+
+    RefPtr<DOMWindow> m_window;
+    RefPtr<MessageEvent> m_event;
+    RefPtr<SecurityOrigin> m_targetOrigin;
+};
+#endif
+
 // This function:
 // 1) Validates the pending changes are not changing to NaN
 // 2) Constrains the window rect to no smaller than 100 in each dimension and no
@@ -325,39 +350,53 @@ Storage* DOMWindow::localStorage() const
 #endif
 
 #if ENABLE(CROSS_DOCUMENT_MESSAGING)
-void DOMWindow::postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode& ecForSender) const
+void DOMWindow::postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
 {
     if (!m_frame)
         return;
 
-    if (!targetOrigin.isNull()) {
-        KURL desiredTargetURL(targetOrigin);
-        if (!desiredTargetURL.isValid()) {
-            ecForSender = SYNTAX_ERR;
-            return;
-        }
-
-        RefPtr<SecurityOrigin> desiredTargetOrigin = SecurityOrigin::create(desiredTargetURL);
-        SecurityOrigin* actualTargetOrigin = document()->securityOrigin();
-        if (desiredTargetOrigin->isEmpty() || !desiredTargetOrigin->isSameSchemeHostPort(actualTargetOrigin)) {
-            // The sender is not allowed to find out the origin of
-            // the recipient, so we fail silently and log a message
-            // to the console.
-            String message = String::format("Unable to post message to %s. Recipient has origin %s.\n", 
-                targetOrigin.utf8().data(), actualTargetOrigin->toString().utf8().data());
-            console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 0, String());
+    // Compute the target origin.  We need to do this synchronously in order
+    // to generate the SYNTAX_ERR exception correctly.
+    RefPtr<SecurityOrigin> target;
+    if (targetOrigin != "*") {
+        target = SecurityOrigin::create(KURL(targetOrigin));
+        if (target->isEmpty()) {
+            ec = SYNTAX_ERR;
             return;
         }
     }
 
+    // Capture the source of the message.  We need to do this synchronously
+    // in order to capture the source of the message correctly.
     Document* sourceDocument = source->document();
     if (!sourceDocument)
         return;
     String sourceOrigin = sourceDocument->securityOrigin()->toString();
 
-    // Sender is not allowed to see exceptions other than syntax errors
-    ExceptionCode ec; 
-    document()->dispatchEvent(new MessageEvent(message, sourceOrigin, source), ec, true);
+    // Schedule the message.
+    PostMessageTimer* timer = new PostMessageTimer(this, new MessageEvent(message, sourceOrigin, source), target.get());
+    timer->startOneShot(0);
+}
+
+void DOMWindow::postMessageTimerFired(PostMessageTimer* t)
+{
+    OwnPtr<PostMessageTimer> timer(t);
+
+    if (!document())
+        return;
+
+    if (timer->targetOrigin()) {
+        // Check target origin now since the target document may have changed since the simer was scheduled.
+        if (!timer->targetOrigin()->isSameSchemeHostPort(document()->securityOrigin())) {
+            String message = String::format("Unable to post message to %s. Recipient has origin %s.\n", 
+                timer->targetOrigin()->toString().utf8().data(), document()->securityOrigin()->toString().utf8().data());
+            console()->addMessage(JSMessageSource, ErrorMessageLevel, message, 0, String());
+            return;
+        }
+    }
+
+    ExceptionCode ec;
+    document()->dispatchEvent(timer->event(), ec, true);
 }
 #endif
 
index 356c0b2..6cf4169 100644 (file)
@@ -50,6 +50,9 @@ namespace WebCore {
     class Frame;
     class History;
     class Location;
+#if ENABLE(CROSS_DOCUMENT_MESSAGING)
+    class PostMessageTimer;
+#endif
     class Navigator;
     class Screen;
 
@@ -172,8 +175,10 @@ namespace WebCore {
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
         DOMApplicationCache* applicationCache() const;
 #endif
+
 #if ENABLE(CROSS_DOCUMENT_MESSAGING)
-        void postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode& ecForSender) const;
+        void postMessage(const String& message, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
+        void postMessageTimerFired(PostMessageTimer*);
 #endif
 
         void scrollBy(int x, int y) const;
index 328da16..d89a274 100644 (file)
@@ -148,7 +148,7 @@ module window {
 
 #if defined(ENABLE_CROSS_DOCUMENT_MESSAGING)
         // cross-document messaging
-        [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] DOMString targetOrigin)
+        [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in DOMString targetOrigin)
             raises(DOMException);
 #endif