diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index f5d5de2859ec..191c9ad9be42 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -584,14 +584,20 @@ TabParent::ReceiveMessage(const nsString& aMessage, nsRefPtr frameLoader = GetFrameLoader(); if (frameLoader && frameLoader->GetFrameMessageManager()) { nsFrameMessageManager* manager = frameLoader->GetFrameMessageManager(); - JSContext* ctx = manager->GetJSContext(); - JSAutoRequest ar(ctx); - PRUint32 len = 0; //TODO: obtain a real value in bug 572685 - // Because we want JS messages to have always the same properties, - // create array even if len == 0. - JSObject* objectsArray = JS_NewArrayObject(ctx, len, NULL); - if (!objectsArray) { - return false; + + // Context may be gone after calling ReceiveMessage, so scope the + // context pointer to prevent dangling. + JSObject* objectsArray; + { + JSContext* ctx = manager->GetJSContext(); + JSAutoRequest ar(ctx); + PRUint32 len = 0; //TODO: obtain a real value in bug 572685 + // Because we want JS messages to have always the same properties, + // create array even if len == 0. + objectsArray = JS_NewArrayObject(ctx, len, NULL); + if (!objectsArray) { + return false; + } } manager->ReceiveMessage(mFrameElement, diff --git a/dom/tests/browser/Makefile.in b/dom/tests/browser/Makefile.in index b76180f75b10..298261177ae3 100644 --- a/dom/tests/browser/Makefile.in +++ b/dom/tests/browser/Makefile.in @@ -51,6 +51,8 @@ _BROWSER_FILES = \ browser_ConsoleAPITests.js \ test-console-api.html \ browser_autofocus_preference.js \ + browser_643083.js \ + test_643083.xul \ $(NULL) libs:: $(_BROWSER_FILES) diff --git a/dom/tests/browser/browser_643083.js b/dom/tests/browser/browser_643083.js new file mode 100644 index 000000000000..a3bd501f24ef --- /dev/null +++ b/dom/tests/browser/browser_643083.js @@ -0,0 +1,38 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +Components.utils.import("resource://gre/modules/Services.jsm"); + +function test() { + waitForExplicitFinish(); + + let win = Services.ww.openWindow( + window, "chrome://mochitests/content/browser/dom/tests/browser/test_643083.xul", "_blank", "chrome", {}); + win.addEventListener("load", function() { + let browser = win.browser(); + browser.messageManager.addMessageListener("scroll", function fn(msg) { + // Calling win.close() will dispatch the close later if the + // JS context of the window is the same as for the win.close() + // call. (See nsGlobalWindow::FinalClose()) + // + // Because the crash needs to happen during the same event that + // we receive the message, we use an event listener and dispatch + // to it synchronously. + // + window.addEventListener("dummy-event", function() { + win.close(); + + setTimeout(function() { + ok(true, "Completed message to close window"); + finish(); + }, 0); + }, false); + + let e = document.createEvent("UIEvents"); + e.initUIEvent("dummy-event", true, false, window, 0); + window.dispatchEvent(e); + + finish(); + }); + }, false); +} diff --git a/dom/tests/browser/test_643083.xul b/dom/tests/browser/test_643083.xul new file mode 100644 index 000000000000..fd4fe06d95e2 --- /dev/null +++ b/dom/tests/browser/test_643083.xul @@ -0,0 +1,33 @@ + + + + + + + + + + + + + +