mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 733035 - postMessage support for sandboxes. r=khuey
This commit is contained in:
parent
477e42fd5d
commit
c306ffc838
@ -5962,8 +5962,7 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsGlobalWindow*
|
||||
nsGlobalWindow::CallerInnerWindow()
|
||||
JSObject* nsGlobalWindow::CallerGlobal()
|
||||
{
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (!cx) {
|
||||
@ -5988,6 +5987,21 @@ nsGlobalWindow::CallerInnerWindow()
|
||||
if (!scope)
|
||||
scope = JS_GetGlobalForScopeChain(cx);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
nsGlobalWindow*
|
||||
nsGlobalWindow::CallerInnerWindow()
|
||||
{
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (!cx) {
|
||||
NS_ERROR("Please don't call this method from C++!");
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSObject *scope = CallerGlobal();
|
||||
|
||||
JSAutoEnterCompartment ac;
|
||||
if (!ac.enter(cx, scope))
|
||||
return nsnull;
|
||||
@ -6310,21 +6324,30 @@ nsGlobalWindow::PostMessageMoz(const jsval& aMessage,
|
||||
|
||||
// First, get the caller's window
|
||||
nsRefPtr<nsGlobalWindow> callerInnerWin = CallerInnerWindow();
|
||||
if (!callerInnerWin)
|
||||
return NS_OK;
|
||||
NS_ABORT_IF_FALSE(callerInnerWin->IsInnerWindow(),
|
||||
"should have gotten an inner window here");
|
||||
nsIPrincipal* callerPrin;
|
||||
if (callerInnerWin) {
|
||||
NS_ABORT_IF_FALSE(callerInnerWin->IsInnerWindow(),
|
||||
"should have gotten an inner window here");
|
||||
|
||||
// Compute the caller's origin either from its principal or, in the case the
|
||||
// principal doesn't carry a URI (e.g. the system principal), the caller's
|
||||
// document. We must get this now instead of when the event is created and
|
||||
// dispatched, because ultimately it is the identity of the calling window
|
||||
// *now* that determines who sent the message (and not an identity which might
|
||||
// have changed due to intervening navigations).
|
||||
nsIPrincipal* callerPrin = callerInnerWin->GetPrincipal();
|
||||
// Compute the caller's origin either from its principal or, in the case the
|
||||
// principal doesn't carry a URI (e.g. the system principal), the caller's
|
||||
// document. We must get this now instead of when the event is created and
|
||||
// dispatched, because ultimately it is the identity of the calling window
|
||||
// *now* that determines who sent the message (and not an identity which might
|
||||
// have changed due to intervening navigations).
|
||||
callerPrin = callerInnerWin->GetPrincipal();
|
||||
}
|
||||
else {
|
||||
// In case the global is not a window, it can be a sandbox, and the sandbox's
|
||||
// principal can be used for the security check.
|
||||
JSObject *global = CallerGlobal();
|
||||
NS_ASSERTION(global, "Why is there no global object?");
|
||||
JSCompartment *compartment = js::GetObjectCompartment(global);
|
||||
callerPrin = xpc::GetCompartmentPrincipal(compartment);
|
||||
}
|
||||
if (!callerPrin)
|
||||
return NS_OK;
|
||||
|
||||
|
||||
nsCOMPtr<nsIURI> callerOuterURI;
|
||||
if (NS_FAILED(callerPrin->GetURI(getter_AddRefs(callerOuterURI))))
|
||||
return NS_OK;
|
||||
@ -6334,15 +6357,20 @@ nsGlobalWindow::PostMessageMoz(const jsval& aMessage,
|
||||
// if the principal has a URI, use that to generate the origin
|
||||
nsContentUtils::GetUTFOrigin(callerPrin, origin);
|
||||
}
|
||||
else {
|
||||
else if (callerInnerWin) {
|
||||
// otherwise use the URI of the document to generate origin
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(callerInnerWin->mDocument);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(callerInnerWin->GetExtantDocument());
|
||||
if (!doc)
|
||||
return NS_OK;
|
||||
callerOuterURI = doc->GetDocumentURI();
|
||||
// if the principal has a URI, use that to generate the origin
|
||||
nsContentUtils::GetUTFOrigin(callerOuterURI, origin);
|
||||
}
|
||||
else {
|
||||
// in case of a sandbox with a system principal origin can be empty
|
||||
if (!nsContentUtils::IsSystemPrincipal(callerPrin))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Convert the provided origin string into a URI for comparison purposes.
|
||||
// "*" indicates no specific origin is required.
|
||||
@ -6358,7 +6386,7 @@ nsGlobalWindow::PostMessageMoz(const jsval& aMessage,
|
||||
// Create and asynchronously dispatch a runnable which will handle actual DOM
|
||||
// event creation and dispatch.
|
||||
nsRefPtr<PostMessageEvent> event =
|
||||
new PostMessageEvent(nsContentUtils::IsCallerChrome()
|
||||
new PostMessageEvent(nsContentUtils::IsCallerChrome() || !callerInnerWin
|
||||
? nsnull
|
||||
: callerInnerWin->GetOuterWindowInternal(),
|
||||
origin,
|
||||
|
@ -575,6 +575,7 @@ protected:
|
||||
nsresult FinalClose();
|
||||
|
||||
void FreeInnerObjects();
|
||||
JSObject *CallerGlobal();
|
||||
nsGlobalWindow *CallerInnerWindow();
|
||||
|
||||
nsresult InnerSetNewDocument(nsIDocument* aDocument);
|
||||
|
@ -77,6 +77,7 @@ _TEST_FILES = \
|
||||
test_moving_nodeList.xul \
|
||||
test_callback_wrapping.xul \
|
||||
window_callback_wrapping.xul \
|
||||
test_sandbox_postMessage.html \
|
||||
$(NULL)
|
||||
|
||||
ifeq (WINNT,$(OS_ARCH))
|
||||
|
36
dom/tests/mochitest/chrome/test_sandbox_postMessage.html
Normal file
36
dom/tests/mochitest/chrome/test_sandbox_postMessage.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Testing postMessage from sandbox</title>
|
||||
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function doTest() {
|
||||
var sandbox = Components.utils.Sandbox("http://mochi.test:8888/", { wantXrays: true });
|
||||
var win = window.frames["sameDomain"];
|
||||
sandbox.win = win;
|
||||
sandbox.is = is;
|
||||
sandbox.done = SimpleTest.finish;
|
||||
|
||||
result = Components.utils.evalInSandbox('var data = {some:"data"};'
|
||||
+'win.addEventListener("message", receiveMessage, false);'
|
||||
+'function receiveMessage(event)'
|
||||
+'{'
|
||||
+' is(JSON.stringify(event.data), JSON.stringify(data), "Received the expected message data");'
|
||||
+' done();'
|
||||
+'}'
|
||||
+'win.postMessage(data, "*")'
|
||||
, sandbox);
|
||||
}
|
||||
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="http://mochi.test:8888/"
|
||||
id="sameDomain" name="sameDomain">
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -223,6 +223,8 @@ bool Base64Decode(JSContext *cx, JS::Value val, JS::Value *out);
|
||||
bool StringToJsval(JSContext *cx, nsAString &str, JS::Value *rval);
|
||||
bool NonVoidStringToJsval(JSContext *cx, nsAString &str, JS::Value *rval);
|
||||
|
||||
nsIPrincipal *GetCompartmentPrincipal(JSCompartment *compartment);
|
||||
|
||||
#ifdef DEBUG
|
||||
void DumpJSHeap(FILE* file);
|
||||
#endif
|
||||
|
@ -45,9 +45,6 @@ class nsIPrincipal;
|
||||
|
||||
namespace xpc {
|
||||
|
||||
nsIPrincipal *
|
||||
GetCompartmentPrincipal(JSCompartment *compartment);
|
||||
|
||||
class AccessCheck {
|
||||
public:
|
||||
static bool isSameOrigin(JSCompartment *a, JSCompartment *b);
|
||||
|
Loading…
Reference in New Issue
Block a user