axmol/scripting/javascript/bindings/js/debugger/tests/unit/test_unsafeDereference.js

135 lines
6.2 KiB
JavaScript

// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
// Test Debugger.Object.prototype.unsafeDereference in the presence of
// interesting cross-compartment wrappers.
//
// This is not really a debugger 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.
Components.utils.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
// Add a method to Debugger.Object for fetching value properties
// conveniently.
Debugger.Object.prototype.getProperty = function (aName) {
let desc = this.getOwnPropertyDescriptor(aName);
if (!desc)
return undefined;
if (!desc.value) {
throw Error("Debugger.Object.prototype.getProperty: " +
"not a value property: " + aName);
}
return desc.value;
};
function run_test() {
// Create a low-privilege sandbox, and a chrome-privilege sandbox.
let contentBox = Components.utils.Sandbox('http://www.example.com');
let chromeBox = Components.utils.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.
var mainObj = { name: "mainObj" };
Components.utils.evalInSandbox('var contentObj = { name: "contentObj" };',
contentBox);
Components.utils.evalInSandbox('var chromeObj = { name: "chromeObj" };',
chromeBox);
// Give each global a pointer to all the other globals' objects.
contentBox.mainObj = chromeBox.mainObj = mainObj;
var contentObj = chromeBox.contentObj = contentBox.contentObj;
var 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.
do_check_true(Components.utils.evalInSandbox('mainObj', contentBox)
=== contentBox.mainObj);
do_check_true(Components.utils.evalInSandbox('contentObj', contentBox)
=== contentBox.contentObj);
do_check_true(Components.utils.evalInSandbox('chromeObj', contentBox)
=== contentBox.chromeObj);
do_check_true(Components.utils.evalInSandbox('mainObj', chromeBox)
=== chromeBox.mainObj);
do_check_true(Components.utils.evalInSandbox('contentObj', chromeBox)
=== chromeBox.contentObj);
do_check_true(Components.utils.evalInSandbox('chromeObj', chromeBox)
=== chromeBox.chromeObj);
// We (the main global) can see properties of all objects in all globals.
do_check_true(contentBox.mainObj.name === "mainObj");
do_check_true(contentBox.contentObj.name === "contentObj");
do_check_true(contentBox.chromeObj.name === "chromeObj");
// chromeBox can see properties of all objects in all globals.
do_check_eq(Components.utils.evalInSandbox('mainObj.name', chromeBox),
'mainObj');
do_check_eq(Components.utils.evalInSandbox('contentObj.name', chromeBox),
'contentObj');
do_check_eq(Components.utils.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.
do_check_eq(Components.utils.evalInSandbox('mainObj.name', contentBox),
undefined);
do_check_eq(Components.utils.evalInSandbox('contentObj.name', contentBox),
'contentObj');
do_check_eq(Components.utils.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.
let dbg = new Debugger;
// Create Debugger.Object instances referring to the two sandboxes, as
// seen from their own compartments.
let contentBoxDO = dbg.addDebuggee(contentBox);
let 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.
let mainFromContentDO = contentBoxDO.getProperty('mainObj');
do_check_eq(mainFromContentDO, contentBoxDO.makeDebuggeeValue(mainObj));
do_check_eq(mainFromContentDO.getProperty('name'), undefined);
do_check_eq(mainFromContentDO.unsafeDereference(), mainObj);
let contentFromContentDO = contentBoxDO.getProperty('contentObj');
do_check_eq(contentFromContentDO, contentBoxDO.makeDebuggeeValue(contentObj));
do_check_eq(contentFromContentDO.getProperty('name'), 'contentObj');
do_check_eq(contentFromContentDO.unsafeDereference(), contentObj);
let chromeFromContentDO = contentBoxDO.getProperty('chromeObj');
do_check_eq(chromeFromContentDO, contentBoxDO.makeDebuggeeValue(chromeObj));
do_check_eq(chromeFromContentDO.getProperty('name'), undefined);
do_check_eq(chromeFromContentDO.unsafeDereference(), chromeObj);
// Similarly, viewing from chromeBox.
let mainFromChromeDO = chromeBoxDO.getProperty('mainObj');
do_check_eq(mainFromChromeDO, chromeBoxDO.makeDebuggeeValue(mainObj));
do_check_eq(mainFromChromeDO.getProperty('name'), 'mainObj');
do_check_eq(mainFromChromeDO.unsafeDereference(), mainObj);
let contentFromChromeDO = chromeBoxDO.getProperty('contentObj');
do_check_eq(contentFromChromeDO, chromeBoxDO.makeDebuggeeValue(contentObj));
do_check_eq(contentFromChromeDO.getProperty('name'), 'contentObj');
do_check_eq(contentFromChromeDO.unsafeDereference(), contentObj);
let chromeFromChromeDO = chromeBoxDO.getProperty('chromeObj');
do_check_eq(chromeFromChromeDO, chromeBoxDO.makeDebuggeeValue(chromeObj));
do_check_eq(chromeFromChromeDO.getProperty('name'), 'chromeObj');
do_check_eq(chromeFromChromeDO.unsafeDereference(), chromeObj);
}