diff options
Diffstat (limited to 'devtools/server/tests/unit/test_unsafeDereference.js')
-rw-r--r-- | devtools/server/tests/unit/test_unsafeDereference.js | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/devtools/server/tests/unit/test_unsafeDereference.js b/devtools/server/tests/unit/test_unsafeDereference.js new file mode 100644 index 000000000..d7afe645f --- /dev/null +++ b/devtools/server/tests/unit/test_unsafeDereference.js @@ -0,0 +1,134 @@ +// 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); +} |