Skip to content

Commit

Permalink
Bug 1141796: Don't inject the SDK console into pages loaded in tabs. …
Browse files Browse the repository at this point in the history
…r=erikvold
  • Loading branch information
Mossop committed Mar 16, 2015
1 parent 0e48308 commit 2752de9
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 1 deletion.
1 change: 1 addition & 0 deletions addon-sdk/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -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',
]
Expand Down
16 changes: 15 additions & 1 deletion addon-sdk/source/lib/sdk/content/sandbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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 ],

Expand Down Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions addon-sdk/source/lib/sdk/remote/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
8 changes: 8 additions & 0 deletions addon-sdk/source/lib/sdk/remote/core.js
Original file line number Diff line number Diff line change
@@ -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;
5 changes: 5 additions & 0 deletions addon-sdk/source/lib/sdk/remote/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions addon-sdk/source/test/addons/e10s-remote/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
19 changes: 19 additions & 0 deletions addon-sdk/source/test/addons/e10s-remote/remote-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions addon-sdk/source/test/addons/remote/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
Expand Down
19 changes: 19 additions & 0 deletions addon-sdk/source/test/addons/remote/remote-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions addon-sdk/source/test/test-page-mod.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit 2752de9

Please sign in to comment.