Bug 1481021: Part 1 - Fix tests that rely on permissive COWs or SpecialPowers side-effects in frame script scopes. r=bz

Right now, a lot of test code relies on side-effects of SpecialPowers being
loaded into frame script globals. In particular:

- It forces permissive COWs from those scopes, which allows frame scripts to
  pass objects from those scopes to unprivileged content that they otherwise
  wouldn't.
- It imports a bunch of helper modules and WebIDL globals which would
  otherwise not be available.

Fortunately, this seems to only impact test code at this point. But there's a
real down-the-road risk of it impacting shipping code, which ends up working
in automation due to the side-effects of SpecialPowers, but failing in real
world use.

MozReview-Commit-ID: G27eSSOHymX

--HG--
extra : rebase_source : 1702e63fed719fc92def2bdbbb8a7c53572432db
extra : source : 41bedc526dd6ec6b7e8c7be1c832ac60c81d6263
This commit is contained in:
Kris Maglione 2018-08-07 14:13:06 -07:00
parent 3b913b0f12
commit 25c94b46d8
13 changed files with 36 additions and 12 deletions

View File

@ -18,6 +18,8 @@ registerCleanupFunction(function() {
// offline cache events.
//
function contentTask() {
ChromeUtils.import("resource://gre/modules/Timer.jsm");
let resolve;
let promise = new Promise(r => { resolve = r; });

View File

@ -92,6 +92,7 @@ add_task(async function test_displayURI_camera() {
add_task(async function test_displayURI_geo_blob() {
await check(async function() {
Cu.importGlobalProperties(["Blob"]);
let text = "<script>navigator.geolocation.getCurrentPosition(() => {})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);
@ -101,6 +102,7 @@ add_task(async function test_displayURI_geo_blob() {
add_task(async function test_displayURI_camera_blob() {
await check(async function() {
Cu.importGlobalProperties(["Blob"]);
let text = "<script>navigator.mediaDevices.getUserMedia({video: true, fake: true})</script>";
let blob = new Blob([text], {type: "text/html"});
let url = content.URL.createObjectURL(blob);

View File

@ -3,6 +3,7 @@
/* eslint-env mozilla/frame-script */
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "MediaManagerService",
"@mozilla.org/mediaManagerService;1",

View File

@ -65,7 +65,7 @@ test_newtab({
// it should be able to click the topsites edit button to reveal the edit topsites modal and overlay.
test: async function topsites_add() {
let nativeInputValueSetter = Object.getOwnPropertyDescriptor(content.window.HTMLInputElement.prototype, "value").set;
let event = new Event("input", {bubbles: true});
let event = new content.Event("input", {bubbles: true});
// Find the add topsites button
content.document.querySelector(".top-sites .section-top-bar .context-menu-button").click();

View File

@ -90,12 +90,12 @@ let PaymentFrameScript = {
},
getDefaultPreferences() {
let prefValues = {
let prefValues = Cu.cloneInto({
saveCreditCardDefaultChecked:
Services.prefs.getBoolPref(SAVE_CREDITCARD_DEFAULT_PREF, false),
saveAddressDefaultChecked:
Services.prefs.getBoolPref(SAVE_ADDRESS_DEFAULT_PREF, false),
};
}, waivedContent);
return prefValues;
},
};

View File

@ -323,7 +323,7 @@ function loadUITourTestPage(callback, host = "https://example.org/") {
let callbacksCalled = 0;
let resolveCallbackPromise;
let allCallbacksCalledPromise = new Promise(resolve => resolveCallbackPromise = resolve);
let argumentsWithFunctions = contentArgs.args.map((arg, index) => {
let argumentsWithFunctions = Cu.cloneInto(contentArgs.args.map((arg, index) => {
if (arg === "" && contentArgs.fnIndices.includes(index)) {
return function() {
callbacksCalled++;
@ -334,9 +334,9 @@ function loadUITourTestPage(callback, host = "https://example.org/") {
};
}
return arg;
});
}), content, {cloneFunctions: true});
let rv = contentWin.Mozilla.UITour[contentArgs.methodName].apply(contentWin.Mozilla.UITour,
argumentsWithFunctions);
argumentsWithFunctions);
if (contentArgs.fnIndices.length) {
await allCallbacksCalledPromise;
}

View File

@ -23,7 +23,7 @@ this.call = function (name, args) {
dump("Calling function with name " + name + ".\n");
dump("args " + JSON.stringify(args) + "\n");
return XPCNativeWrapper.unwrap(content)[name].apply(undefined, args);
return XPCNativeWrapper.unwrap(content)[name].apply(undefined, Cu.cloneInto(args, content));
};
this._eval = function (string) {

View File

@ -72,6 +72,8 @@ function testKeys(browser) {
function testOpen_worker(browser) {
return ContentTask.spawn(browser, {}, function() {
Cu.importGlobalProperties(["Blob"]);
let workerFunctionString = function () {
caches.open("pb-worker-cache").then(function(cacheObject) {
postMessage(cacheObject.toString());

View File

@ -11,6 +11,7 @@ add_task(async function test_CtoPtoC_big() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
let blob = new Blob([new Array(1024*1024).join('123456789ABCDEF')]);
return blob;
});
@ -43,6 +44,7 @@ add_task(async function test_CtoPtoC_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
let blob = new Blob(["hello world!"]);
return blob;
});
@ -75,6 +77,7 @@ add_task(async function test_CtoPtoC_bc_big() {
let browser1 = gBrowser.getBrowserForTab(tab1);
await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
var bc = new content.BroadcastChannel('test');
bc.onmessage = function() {
bc.postMessage(new Blob([new Array(1024*1024).join('123456789ABCDEF')]));
@ -111,6 +114,7 @@ add_task(async function test_CtoPtoC_bc_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
var bc = new content.BroadcastChannel('test');
bc.onmessage = function() {
bc.postMessage(new Blob(["hello world!"]));
@ -147,6 +151,7 @@ add_task(async function test_CtoPtoC_bc_small() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blobURL = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
return content.URL.createObjectURL(new content.Blob(["hello world!"]));
});
@ -177,6 +182,7 @@ add_task(async function test_CtoPtoC_multipart() {
let browser1 = gBrowser.getBrowserForTab(tab1);
let blob = await ContentTask.spawn(browser1, null, function() {
Cu.importGlobalProperties(["Blob"]);
return new Blob(["!"]);
});
@ -189,6 +195,7 @@ add_task(async function test_CtoPtoC_multipart() {
let browser2 = gBrowser.getBrowserForTab(tab2);
let status = await ContentTask.spawn(browser2, newBlob, function(blob) {
Cu.importGlobalProperties(["Blob"]);
return new Promise(resolve => {
let fr = new content.FileReader();
fr.readAsText(new Blob(["hello ", blob]));

View File

@ -18,7 +18,7 @@ function frameScript() {
});
addMessageListener("Test:DispatchUntrustedKeyEvents", msg => {
var evt = new content.CustomEvent("Test:DispatchKeyEvents", {
detail: { code: msg.data }
detail: Cu.cloneInto({ code: msg.data }, content),
});
content.dispatchEvent(evt);
});

View File

@ -160,7 +160,7 @@ async function mutateTabStorage(knownTab, mutations, sentinelValue) {
knownTab.tab.linkedBrowser,
{ mutations, sentinelValue },
function(args) {
return content.wrappedJSObject.mutateStorage(args);
return content.wrappedJSObject.mutateStorage(Cu.cloneInto(args, content));
});
}

View File

@ -19,7 +19,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=628410
<script type="application/javascript">
/** Test for Bug 628410 **/
window.toSource();
{
// window.toSource() will throw if SpecialPowers is defined on the window and
// permissive COWs are not enabled for the global that owns its frame message
// manager.
let sp = window.SpecialPowers;
window.SpecialPowers = null;
window.toSource();
window.SpecialPowers = sp;
}
window.toString();
InstallTrigger + "";
console + "";

View File

@ -21,8 +21,6 @@ const kPageURL =
const environment = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
const InspectorUtils = SpecialPowers.InspectorUtils;
// Parameters for running the python script that registers/unregisters fonts.
const kPythonPath = "/usr/bin/python";
const kFontInstallerPath = "browser/security/sandbox/test/mac_register_font.py";
@ -128,6 +126,8 @@ add_task(async function() {
// Get a list of fonts being used to display the web content.
let fontList = await ContentTask.spawn(aBrowser, {}, async function() {
Cu.importGlobalProperties(["InspectorUtils"]);
let window = content.window.wrappedJSObject;
let range = window.document.createRange();
let contentDiv = window.document.getElementById("content");