1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
/* eslint-disable strict */
// Test Debugger.Object.prototype.unsafeDereference in the presence of
// interesting cross-compartment wrappers.
//
// This is not really a devtools server test; it's more of a Debugger test.
// But we need xpcshell and Components.utils.Sandbox to get
// cross-compartment wrappers with interesting properties, and this is the
// xpcshell test directory most closely related to the JS Debugger API.
addDebuggerToGlobal(globalThis);
// Add a method to Debugger.Object for fetching value properties
// conveniently.
Debugger.Object.prototype.getProperty = function (name) {
const desc = this.getOwnPropertyDescriptor(name);
if (!desc) {
return undefined;
}
if (!desc.value) {
throw Error(
"Debugger.Object.prototype.getProperty: " +
"not a value property: " +
name
);
}
return desc.value;
};
function run_test() {
// Create a low-privilege sandbox, and a chrome-privilege sandbox.
const contentBox = Cu.Sandbox("http://www.example.com");
const chromeBox = Cu.Sandbox(this);
// Create an objects in this compartment, and one in each sandbox. We'll
// refer to the objects as "mainObj", "contentObj", and "chromeObj", in
// variable and property names.
const mainObj = { name: "mainObj" };
Cu.evalInSandbox('var contentObj = { name: "contentObj" };', contentBox);
Cu.evalInSandbox('var chromeObj = { name: "chromeObj" };', chromeBox);
// Give each global a pointer to all the other globals' objects.
contentBox.mainObj = chromeBox.mainObj = mainObj;
const contentObj = (chromeBox.contentObj = contentBox.contentObj);
const chromeObj = (contentBox.chromeObj = chromeBox.chromeObj);
// First, a whole bunch of basic sanity checks, to ensure that JavaScript
// evaluated in various scopes really does see the world the way this
// test expects it to.
// The objects appear as global variables in the sandbox, and as
// the sandbox object's properties in chrome.
Assert.strictEqual(
Cu.evalInSandbox("mainObj", contentBox),
contentBox.mainObj
);
Assert.strictEqual(
Cu.evalInSandbox("contentObj", contentBox),
contentBox.contentObj
);
Assert.strictEqual(
Cu.evalInSandbox("chromeObj", contentBox),
contentBox.chromeObj
);
Assert.strictEqual(Cu.evalInSandbox("mainObj", chromeBox), chromeBox.mainObj);
Assert.strictEqual(
Cu.evalInSandbox("contentObj", chromeBox),
chromeBox.contentObj
);
Assert.strictEqual(
Cu.evalInSandbox("chromeObj", chromeBox),
chromeBox.chromeObj
);
// We (the main global) can see properties of all objects in all globals.
Assert.strictEqual(contentBox.mainObj.name, "mainObj");
Assert.strictEqual(contentBox.contentObj.name, "contentObj");
Assert.strictEqual(contentBox.chromeObj.name, "chromeObj");
// chromeBox can see properties of all objects in all globals.
Assert.equal(Cu.evalInSandbox("mainObj.name", chromeBox), "mainObj");
Assert.equal(Cu.evalInSandbox("contentObj.name", chromeBox), "contentObj");
Assert.equal(Cu.evalInSandbox("chromeObj.name", chromeBox), "chromeObj");
// contentBox can see properties of the content object, but not of either
// chrome object, because by default, content -> chrome wrappers hide all
// object properties.
Assert.equal(Cu.evalInSandbox("mainObj.name", contentBox), undefined);
Assert.equal(Cu.evalInSandbox("contentObj.name", contentBox), "contentObj");
Assert.equal(Cu.evalInSandbox("chromeObj.name", contentBox), undefined);
// When viewing an object in compartment A from the vantage point of
// compartment B, Debugger should give the same results as debuggee code
// would.
// Create a debugger, debugging our two sandboxes.
const dbg = new Debugger();
// Create Debugger.Object instances referring to the two sandboxes, as
// seen from their own compartments.
const contentBoxDO = dbg.addDebuggee(contentBox);
const chromeBoxDO = dbg.addDebuggee(chromeBox);
// Use Debugger to view the objects from contentBox. We should get the
// same D.O instance from both getProperty and makeDebuggeeValue, and the
// same property visibility we checked for above.
const mainFromContentDO = contentBoxDO.getProperty("mainObj");
Assert.equal(mainFromContentDO, contentBoxDO.makeDebuggeeValue(mainObj));
Assert.equal(mainFromContentDO.getProperty("name"), undefined);
Assert.equal(mainFromContentDO.unsafeDereference(), mainObj);
const contentFromContentDO = contentBoxDO.getProperty("contentObj");
Assert.equal(
contentFromContentDO,
contentBoxDO.makeDebuggeeValue(contentObj)
);
Assert.equal(contentFromContentDO.getProperty("name"), "contentObj");
Assert.equal(contentFromContentDO.unsafeDereference(), contentObj);
const chromeFromContentDO = contentBoxDO.getProperty("chromeObj");
Assert.equal(chromeFromContentDO, contentBoxDO.makeDebuggeeValue(chromeObj));
Assert.equal(chromeFromContentDO.getProperty("name"), undefined);
Assert.equal(chromeFromContentDO.unsafeDereference(), chromeObj);
// Similarly, viewing from chromeBox.
const mainFromChromeDO = chromeBoxDO.getProperty("mainObj");
Assert.equal(mainFromChromeDO, chromeBoxDO.makeDebuggeeValue(mainObj));
Assert.equal(mainFromChromeDO.getProperty("name"), "mainObj");
Assert.equal(mainFromChromeDO.unsafeDereference(), mainObj);
const contentFromChromeDO = chromeBoxDO.getProperty("contentObj");
Assert.equal(contentFromChromeDO, chromeBoxDO.makeDebuggeeValue(contentObj));
Assert.equal(contentFromChromeDO.getProperty("name"), "contentObj");
Assert.equal(contentFromChromeDO.unsafeDereference(), contentObj);
const chromeFromChromeDO = chromeBoxDO.getProperty("chromeObj");
Assert.equal(chromeFromChromeDO, chromeBoxDO.makeDebuggeeValue(chromeObj));
Assert.equal(chromeFromChromeDO.getProperty("name"), "chromeObj");
Assert.equal(chromeFromChromeDO.unsafeDereference(), chromeObj);
}
|