Commit 5b07fb4d authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Implement targetOrigin for postMessage.

parent 619312fd
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "winuser.h" #include "winuser.h"
#include "ole2.h" #include "ole2.h"
#include "mshtmdid.h" #include "mshtmdid.h"
#include "wininet.h"
#include "shlguid.h" #include "shlguid.h"
#include "shobjidl.h" #include "shobjidl.h"
#include "exdispid.h" #include "exdispid.h"
...@@ -2218,7 +2219,7 @@ static HRESULT WINAPI HTMLWindow6_postMessage(IHTMLWindow6 *iface, BSTR msg, VAR ...@@ -2218,7 +2219,7 @@ static HRESULT WINAPI HTMLWindow6_postMessage(IHTMLWindow6 *iface, BSTR msg, VAR
HTMLWindow *This = impl_from_IHTMLWindow6(iface); HTMLWindow *This = impl_from_IHTMLWindow6(iface);
VARIANT var, transfer; VARIANT var, transfer;
FIXME("(%p)->(%s %s) semi-stub\n", This, debugstr_w(msg), debugstr_variant(&targetOrigin)); TRACE("(%p)->(%s %s)\n", This, debugstr_w(msg), debugstr_variant(&targetOrigin));
if(V_VT(&targetOrigin) != VT_BSTR) if(V_VT(&targetOrigin) != VT_BSTR)
return E_INVALIDARG; return E_INVALIDARG;
...@@ -3155,6 +3156,69 @@ static HRESULT WINAPI window_private_matchMedia(IWineHTMLWindowPrivate *iface, B ...@@ -3155,6 +3156,69 @@ static HRESULT WINAPI window_private_matchMedia(IWineHTMLWindowPrivate *iface, B
return create_media_query_list(This, media_query, media_query_list); return create_media_query_list(This, media_query, media_query_list);
} }
static HRESULT check_target_origin(HTMLInnerWindow *window, const WCHAR *target_origin)
{
IUri *uri, *target;
DWORD port, port2;
BSTR bstr, bstr2;
HRESULT hres;
if(!target_origin)
return E_INVALIDARG;
if(!wcscmp(target_origin, L"*"))
return S_OK;
hres = create_uri(target_origin, Uri_CREATE_NOFRAG | Uri_CREATE_NO_DECODE_EXTRA_INFO, &target);
if(FAILED(hres))
return hres;
if(!(uri = window->base.outer_window->uri)) {
FIXME("window with no URI\n");
hres = S_FALSE;
goto done;
}
hres = IUri_GetSchemeName(uri, &bstr);
if(FAILED(hres))
goto done;
hres = IUri_GetSchemeName(target, &bstr2);
if(SUCCEEDED(hres)) {
hres = !wcsicmp(bstr, bstr2) ? S_OK : S_FALSE;
SysFreeString(bstr2);
}
SysFreeString(bstr);
if(hres != S_OK)
goto done;
hres = IUri_GetHost(uri, &bstr);
if(FAILED(hres))
goto done;
hres = IUri_GetHost(target, &bstr2);
if(SUCCEEDED(hres)) {
hres = !wcsicmp(bstr, bstr2) ? S_OK : S_FALSE;
SysFreeString(bstr2);
}
SysFreeString(bstr);
if(hres != S_OK)
goto done;
/* Legacy modes ignore port */
if(dispex_compat_mode(&window->event_target.dispex) < COMPAT_MODE_IE9)
goto done;
hres = IUri_GetPort(uri, &port);
if(FAILED(hres))
goto done;
hres = IUri_GetPort(target, &port2);
if(SUCCEEDED(hres))
hres = (port == port2) ? S_OK : S_FALSE;
done:
IUri_Release(target);
return hres;
}
static HRESULT WINAPI window_private_postMessage(IWineHTMLWindowPrivate *iface, VARIANT msg, BSTR targetOrigin, VARIANT transfer) static HRESULT WINAPI window_private_postMessage(IWineHTMLWindowPrivate *iface, VARIANT msg, BSTR targetOrigin, VARIANT transfer)
{ {
HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface); HTMLWindow *This = impl_from_IWineHTMLWindowPrivateVtbl(iface);
...@@ -3168,6 +3232,10 @@ static HRESULT WINAPI window_private_postMessage(IWineHTMLWindowPrivate *iface, ...@@ -3168,6 +3232,10 @@ static HRESULT WINAPI window_private_postMessage(IWineHTMLWindowPrivate *iface,
if(V_VT(&transfer) != VT_EMPTY) if(V_VT(&transfer) != VT_EMPTY)
FIXME("transfer not implemented, ignoring\n"); FIXME("transfer not implemented, ignoring\n");
hres = check_target_origin(window, targetOrigin);
if(hres != S_OK)
return SUCCEEDED(hres) ? S_OK : hres;
switch(V_VT(&msg)) { switch(V_VT(&msg)) {
case VT_EMPTY: case VT_EMPTY:
case VT_NULL: case VT_NULL:
......
...@@ -2082,10 +2082,57 @@ async_test("postMessage", function() { ...@@ -2082,10 +2082,57 @@ async_test("postMessage", function() {
onmessage_called = true; onmessage_called = true;
if(v < 9) if(v < 9)
ok(e === undefined, "e = " + e); ok(e === undefined, "e = " + e);
else else {
ok(e.data === (v < 10 ? "10" : 10), "e.data = " + e.data); ok(e.data === (v < 10 ? "10" : 10), "e.data = " + e.data);
next_test(); next_test();
}
}
var invalid = [
v < 10 ? { toString: function() { return "http://winetest.example.org"; } } : null,
(function() { return "http://winetest.example.org"; }),
"winetest.example.org",
"example.org",
undefined
];
for(var i = 0; i < invalid.length; i++) {
try {
window.postMessage("invalid " + i, invalid[i]);
ok(false, "expected exception with targetOrigin " + invalid[i]);
}catch(ex) {
var n = ex.number >>> 0;
todo_wine_if(v >= 10).
ok(n === (v < 10 ? 0x80070057 : 0), "postMessage with targetOrigin " + invalid[i] + " threw " + n);
if(v >= 10)
todo_wine.
ok(ex.name === "SyntaxError", "postMessage with targetOrigin " + invalid[i] + " threw " + ex.name);
}
} }
window.postMessage(10, "*"); try {
window.postMessage("invalid empty", "");
ok(false, "expected exception with empty targetOrigin");
}catch(ex) {
var n = ex.number >>> 0;
ok(n === 0x80070057, "postMessage with empty targetOrigin threw " + n);
}
window.postMessage("wrong port", "http://winetest.example.org:1234");
ok(onmessage_called == (v < 9 ? true : false), "onmessage not called with wrong port");
onmessage_called = false;
var not_sent = [
"http://winetest.example.com",
"ftp://winetest.example.org",
"http://wine.example.org",
"http://example.org"
];
for(var i = 0; i < not_sent.length; i++) {
window.postMessage("not_sent " + i, not_sent[i]);
ok(onmessage_called == false, "onmessage called with targetOrigin " + not_sent[i]);
onmessage_called = false;
}
window.postMessage(10, (v < 10 ? "*" : { toString: function() { return "*"; } }));
ok(onmessage_called == (v < 9 ? true : false), "onmessage not called"); ok(onmessage_called == (v < 9 ? true : false), "onmessage not called");
if(v < 9) next_test();
}); });
...@@ -818,6 +818,6 @@ async_test("message event", function() { ...@@ -818,6 +818,6 @@ async_test("message event", function() {
next_test(); next_test();
}); });
window.postMessage("test", "http://winetest.example.org"); window.postMessage("test", "httP://wineTest.example.org");
ok(listener_called == false, "listener already called"); ok(listener_called == false, "listener already called");
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment