Bug 1742491 - [remote] Filter out parent process frames in MessageHandlerFrameChild r=webdriver-reviewers,whimboo

Differential Revision: https://phabricator.services.mozilla.com/D131897
This commit is contained in:
Julian Descottes 2021-12-17 09:48:50 +00:00
Родитель f9a4a6bd64
Коммит 78e5eb0c46
8 изменённых файлов: 139 добавлений и 33 удалений

Просмотреть файл

@ -38,6 +38,7 @@ remote.jar:
content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm (shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm)
content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameChild.jsm (shared/messagehandler/transports/js-window-actors/MessageHandlerFrameChild.jsm)
content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameParent.jsm (shared/messagehandler/transports/js-window-actors/MessageHandlerFrameParent.jsm)
content/shared/messagehandler/transports/FrameContextUtils.jsm (shared/messagehandler/transports/FrameContextUtils.jsm)
content/shared/messagehandler/transports/FrameTransport.jsm (shared/messagehandler/transports/FrameTransport.jsm)
# shared modules (WebDriver HTTP / BiDi only)

Просмотреть файл

@ -13,4 +13,5 @@ prefs =
[browser_registry.js]
[browser_session_data.js]
[browser_session_data_broadcast.js]
[browser_session_data_browser_element.js]
[browser_session_data_constructor_race.js]

Просмотреть файл

@ -10,8 +10,8 @@ const { RootMessageHandler } = ChromeUtils.import(
const TEST_PAGE = "https://example.com/document-builder.sjs?html=tab";
add_task(async function test_session_data_broadcast() {
const tab1 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
await BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
const tab1 = gBrowser.selectedTab;
await loadURL(tab1.linkedBrowser, TEST_PAGE);
const browsingContext1 = tab1.linkedBrowser.browsingContext;
const root = createRootMessageHandler("session-id-event");
@ -87,7 +87,6 @@ add_task(async function test_session_data_broadcast() {
root.destroy();
gBrowser.removeTab(tab1);
gBrowser.removeTab(tab2);
});

Просмотреть файл

@ -0,0 +1,73 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_PAGE = "https://example.com/document-builder.sjs?html=tab";
/**
* Check that message handlers are not created for parent process browser
* elements, even if they have the type="content" attribute (eg used for the
* DevTools toolbox).
*/
add_task(async function test_session_data_broadcast() {
const tab1 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
const contentBrowser1 = tab1.linkedBrowser;
await BrowserTestUtils.browserLoaded(contentBrowser1);
const parentBrowser1 = createParentBrowserElement(tab1, "content");
const parentBrowser2 = createParentBrowserElement(tab1, "chrome");
const root = createRootMessageHandler("session-id-event");
info("Add a new session data item, expect one return value");
await root.addSessionData({
moduleName: "command",
category: "browser_session_data_browser_element",
contextDescriptor: {
type: CONTEXT_DESCRIPTOR_TYPES.ALL,
},
values: [true],
});
info(
"Check that only the content tab window global received the session data"
);
is(await hasSessionDataFlag(contentBrowser1), true);
is(await hasSessionDataFlag(parentBrowser1), undefined);
is(await hasSessionDataFlag(parentBrowser2), undefined);
const tab2 = BrowserTestUtils.addTab(gBrowser, TEST_PAGE);
const contentBrowser2 = tab2.linkedBrowser;
await BrowserTestUtils.browserLoaded(contentBrowser2);
const parentBrowser3 = createParentBrowserElement(contentBrowser2, "content");
const parentBrowser4 = createParentBrowserElement(contentBrowser2, "chrome");
info("Wait until the session data was applied to the new tab");
await SpecialPowers.spawn(contentBrowser2, [], async () => {
await ContentTaskUtils.waitForCondition(() => content.hasSessionDataFlag);
});
info("Check that parent browser elements did not apply the session data");
is(await hasSessionDataFlag(parentBrowser3), undefined);
is(await hasSessionDataFlag(parentBrowser4), undefined);
root.destroy();
gBrowser.removeTab(tab1);
gBrowser.removeTab(tab2);
});
function hasSessionDataFlag(browser) {
return SpecialPowers.spawn(browser, [], () => {
return content.hasSessionDataFlag;
});
}
function createParentBrowserElement(tab, type) {
const parentBrowser = gBrowser.ownerDocument.createXULElement("browser");
parentBrowser.setAttribute("type", type);
const container = gBrowser.getBrowserContainer(tab.linkedBrowser);
container.appendChild(parentBrowser);
return parentBrowser;
}

Просмотреть файл

@ -40,6 +40,12 @@ class Command extends Module {
};
}
if (params.category === "browser_session_data_browser_element") {
BrowsingContext.get(
this.messageHandler.contextId
).window.hasSessionDataFlag = true;
}
return {};
}

Просмотреть файл

@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EXPORTED_SYMBOLS = ["isBrowsingContextCompatible"];
function getOsPid(browsingContext) {
if (browsingContext instanceof CanonicalBrowsingContext) {
return browsingContext.currentWindowGlobal.osPid;
}
return browsingContext.window.osPid;
}
/**
* Check if the given browsing context is valid for the message handler
* to use.
*
* @param {BrowsingContext} browsingContext
* The browsing context to check.
* @param {Object=} options
* @param {String=} options.browserId
* The id of the browser to filter the browsing contexts by (optional).
* @return {Boolean}
* True if the browsing context is valid, false otherwise.
*/
function isBrowsingContextCompatible(browsingContext, options = {}) {
const { browserId } = options;
// If a browserId was provided, skip browsing contexts which are not
// associated with this browserId.
if (browserId !== undefined && browsingContext.browserId !== browserId) {
return false;
}
// Skip window globals running in the parent process, unless we want to
// support debugging Chrome context, see Bug 1713440.
if (getOsPid(browsingContext) === -1) {
return false;
}
return true;
}

Просмотреть файл

@ -15,6 +15,8 @@ XPCOMUtils.defineLazyModuleGetters(this, {
CONTEXT_DESCRIPTOR_TYPES:
"chrome://remote/content/shared/messagehandler/MessageHandler.jsm",
isBrowsingContextCompatible:
"chrome://remote/content/shared/messagehandler/transports/FrameContextUtils.jsm",
MessageHandlerFrameActor:
"chrome://remote/content/shared/messagehandler/transports/js-window-actors/MessageHandlerFrameActor.jsm",
});
@ -148,38 +150,13 @@ class FrameTransport {
}
for (const { browsingContext } of win.gBrowser.browsers) {
// Skip window globals running in the parent process, unless we want to
// support debugging Chrome context, see Bug 1713440.
const isChrome = browsingContext.currentWindowGlobal.osPid === -1;
// Skip temporary initial documents that are about to be replaced by
// another document. The new document will be linked to a new window
// global, new JSWindowActors, etc. So attempting to forward any command
// to the temporary initial document would be useless as it has no
// connection to the real document that will be loaded shortly after.
// The new document will be handled as a new context, which should rely
// on session data (Bug 1713443) to setup the necessary configuration
// , events, etc.
const isInitialDocument =
browsingContext.currentWindowGlobal.isInitialDocument;
if (isChrome || isInitialDocument) {
continue;
}
// If a browserId was provided, skip browsing contexts which are not
// associated with this browserId.
if (
typeof browserId !== "undefined" &&
browsingContext.browserId !== browserId
) {
continue;
}
if (isBrowsingContextCompatible(browsingContext, { browserId })) {
browsingContexts = browsingContexts.concat(
browsingContext.getAllBrowsingContextsInSubtree()
);
}
}
}
return browsingContexts;
}

Просмотреть файл

@ -12,6 +12,8 @@ const { XPCOMUtils } = ChromeUtils.import(
XPCOMUtils.defineLazyModuleGetters(this, {
error: "chrome://remote/content/shared/messagehandler/Errors.jsm",
isBrowsingContextCompatible:
"chrome://remote/content/shared/messagehandler/transports/FrameContextUtils.jsm",
MessageHandlerRegistry:
"chrome://remote/content/shared/messagehandler/MessageHandlerRegistry.jsm",
WindowGlobalMessageHandler:
@ -40,9 +42,11 @@ class MessageHandlerFrameChild extends JSWindowActorChild {
handleEvent({ type }) {
if (type == "DOMWindowCreated") {
if (isBrowsingContextCompatible(this.manager.browsingContext)) {
this._registry.createAllMessageHandlers();
}
}
}
async receiveMessage(message) {
if (message.name === "MessageHandlerFrameParent:sendCommand") {