Bug 1141796: Don't inject the SDK console into pages loaded in tabs. r=erikvold

This commit is contained in:
Dave Townsend 2015-03-16 11:31:14 -07:00
parent 0e483088db
commit 2752de9a55
10 changed files with 152 additions and 1 deletions

View File

@ -397,6 +397,7 @@ EXTRA_JS_MODULES.commonjs.sdk['private-browsing'] += [
EXTRA_JS_MODULES.commonjs.sdk.remote += [
'source/lib/sdk/remote/child.js',
'source/lib/sdk/remote/core.js',
'source/lib/sdk/remote/parent.js',
'source/lib/sdk/remote/utils.js',
]

View File

@ -21,6 +21,7 @@ const { getTabForContentWindow } = require('../tabs/utils');
const { getInnerId } = require('../window/utils');
const { PlainTextConsole } = require('../console/plain-text');
const { data } = require('../self');
const { isChildLoader } = require('../remote/core');
// WeakMap of sandboxes so we can access private values
const sandboxes = new WeakMap();
@ -47,6 +48,19 @@ const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
const JS_VERSION = '1.8';
// Tests whether this window is loaded in a tab
function isWindowInTab(window) {
if (isChildLoader) {
let { frames } = require('../remote/child');
let frame = frames.getFrameForWindow(window.top);
return frame.isTab;
}
else {
// The deprecated sync worker API still does everything in the main process
return getTabForContentWindow(window);
}
}
const WorkerSandbox = Class({
implements: [ EventTarget ],
@ -202,7 +216,7 @@ const WorkerSandbox = Class({
// Inject our `console` into target document if worker doesn't have a tab
// (e.g Panel, PageWorker, Widget).
// `worker.tab` can't be used because bug 804935.
if (!getTabForContentWindow(window)) {
if (!isWindowInTab(window)) {
let win = getUnsafeWindow(window);
// export our chrome console to content window, as described here:

View File

@ -3,6 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { isChildLoader } = require('./core');
if (!isChildLoader)
throw new Error("Cannot load sdk/remote/child in a main process loader.");
const { Ci, Cc } = require('chrome');
const runtime = require('../system/runtime');
const { Class } = require('../core/heritage');

View File

@ -0,0 +1,8 @@
/* 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 options = require("@loader/options");
exports.isChildLoader = options.childLoader;

View File

@ -3,6 +3,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { isChildLoader } = require('./core');
if (isChildLoader)
throw new Error("Cannot load sdk/remote/parent in a child loader.");
const { Cu, Ci, Cc } = require('chrome');
const runtime = require('../system/runtime');
@ -53,6 +57,7 @@ catch (e) {
}
const loaderID = getNewLoaderID();
childOptions.loaderID = loaderID;
childOptions.childLoader = true;
const ppmm = Cc['@mozilla.org/parentprocessmessagemanager;1'].
getService(Ci.nsIMessageBroadcaster);

View File

@ -492,8 +492,37 @@ exports["test processID"] = function*(assert) {
assert.equal(ID, processID, "Remote processes should have the same process ID");
}
}
loader.unload();
}
// Check that sdk/remote/parent and sdk/remote/child can only be loaded in the
// appropriate loaders
exports["test cannot load in wrong loader"] = function*(assert) {
let loader = new Loader(module);
let { processes } = yield waitForProcesses(loader);
try {
require('sdk/remote/child');
assert.fail("Should not have been able to load sdk/remote/child");
}
catch (e) {
assert.ok(/Cannot load sdk\/remote\/child in a main process loader/.test(e),
"Should have seen the right exception.");
}
for (let process of processes) {
processes.port.emit('sdk/test/parentload');
let [_, isChildLoader, loaded, message] = yield promiseEvent(processes.port, 'sdk/test/parentload');
assert.ok(isChildLoader, "Process should see itself in a child loader.");
assert.ok(!loaded, "Process couldn't load sdk/remote/parent.");
assert.ok(/Cannot load sdk\/remote\/parent in a child loader/.test(message),
"Should have seen the right exception.");
}
loader.unload();
};
after(exports, function*(name, assert) {
yield cleanUI();
});

View File

@ -8,6 +8,7 @@ const { loaderID } = require('@loader/options');
const { processID } = require('sdk/system/runtime');
const system = require('sdk/system/events');
const { Cu } = require('chrome');
const { isChildLoader } = require('sdk/remote/core');
function log(str) {
console.log("remote[" + loaderID + "][" + processID + "]: " + str);
@ -81,6 +82,24 @@ frames.port.on('sdk/test/sendevent', (frame) => {
frame.port.emit('sdk/test/eventsent');
});
process.port.on('sdk/test/parentload', () => {
let loaded = false;
let message = "";
try {
require('sdk/remote/parent');
loaded = true;
}
catch (e) {
message = "" + e;
}
process.port.emit('sdk/test/parentload',
isChildLoader,
loaded,
message
)
});
function listener(event) {
// Use the raw observer service here since it will be usable even if the
// loader has unloaded

View File

@ -492,8 +492,37 @@ exports["test processID"] = function*(assert) {
assert.equal(ID, processID, "Remote processes should have the same process ID");
}
}
loader.unload();
}
// Check that sdk/remote/parent and sdk/remote/child can only be loaded in the
// appropriate loaders
exports["test cannot load in wrong loader"] = function*(assert) {
let loader = new Loader(module);
let { processes } = yield waitForProcesses(loader);
try {
require('sdk/remote/child');
assert.fail("Should not have been able to load sdk/remote/child");
}
catch (e) {
assert.ok(/Cannot load sdk\/remote\/child in a main process loader/.test(e),
"Should have seen the right exception.");
}
for (let process of processes) {
processes.port.emit('sdk/test/parentload');
let [_, isChildLoader, loaded, message] = yield promiseEvent(processes.port, 'sdk/test/parentload');
assert.ok(isChildLoader, "Process should see itself in a child loader.");
assert.ok(!loaded, "Process couldn't load sdk/remote/parent.");
assert.ok(/Cannot load sdk\/remote\/parent in a child loader/.test(message),
"Should have seen the right exception.");
}
loader.unload();
};
after(exports, function*(name, assert) {
yield cleanUI();
});

View File

@ -8,6 +8,7 @@ const { loaderID } = require('@loader/options');
const { processID } = require('sdk/system/runtime');
const system = require('sdk/system/events');
const { Cu } = require('chrome');
const { isChildLoader } = require('sdk/remote/core');
function log(str) {
console.log("remote[" + loaderID + "][" + processID + "]: " + str);
@ -81,6 +82,24 @@ frames.port.on('sdk/test/sendevent', (frame) => {
frame.port.emit('sdk/test/eventsent');
});
process.port.on('sdk/test/parentload', () => {
let loaded = false;
let message = "";
try {
require('sdk/remote/parent');
loaded = true;
}
catch (e) {
message = "" + e;
}
process.port.emit('sdk/test/parentload',
isChildLoader,
loaded,
message
)
});
function listener(event) {
// Use the raw observer service here since it will be usable even if the
// loader has unloaded

View File

@ -2040,4 +2040,27 @@ exports.testUnloadWontAttach = function(assert, done) {
let tab = openTab(getMostRecentBrowserWindow(), TEST_URL);
}
// Tests that the SDK console isn't injected into documents loaded in tabs
exports.testDontInjectConsole = function(assert, done) {
const TEST_URL = 'data:text/html;charset=utf-8,consoleinject';
let loader = Loader(module);
let mod = PageMod({
include: TEST_URL,
contentScript: Isolate(function() {
// This relies on the fact that the SDK console doesn't have assert defined
self.postMessage((typeof unsafeWindow.console.assert) == "function");
}),
onMessage: isNativeConsole => {
assert.ok(isNativeConsole, "Shouldn't have injected the SDK console.");
mod.destroy();
closeTab(tab);
done();
}
});
let tab = openTab(getMostRecentBrowserWindow(), TEST_URL);
}
require('sdk/test').run(exports);