1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/devtools/server/tests/unit/test_unsafeDereference.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,134 @@ 1.4 +// Any copyright is dedicated to the Public Domain. 1.5 +// http://creativecommons.org/publicdomain/zero/1.0/ 1.6 + 1.7 +// Test Debugger.Object.prototype.unsafeDereference in the presence of 1.8 +// interesting cross-compartment wrappers. 1.9 +// 1.10 +// This is not really a debugger server test; it's more of a Debugger test. 1.11 +// But we need xpcshell and Components.utils.Sandbox to get 1.12 +// cross-compartment wrappers with interesting properties, and this is the 1.13 +// xpcshell test directory most closely related to the JS Debugger API. 1.14 + 1.15 +Components.utils.import("resource://gre/modules/jsdebugger.jsm"); 1.16 +addDebuggerToGlobal(this); 1.17 + 1.18 +// Add a method to Debugger.Object for fetching value properties 1.19 +// conveniently. 1.20 +Debugger.Object.prototype.getProperty = function (aName) { 1.21 + let desc = this.getOwnPropertyDescriptor(aName); 1.22 + if (!desc) 1.23 + return undefined; 1.24 + if (!desc.value) { 1.25 + throw Error("Debugger.Object.prototype.getProperty: " + 1.26 + "not a value property: " + aName); 1.27 + } 1.28 + return desc.value; 1.29 +}; 1.30 + 1.31 +function run_test() { 1.32 + // Create a low-privilege sandbox, and a chrome-privilege sandbox. 1.33 + let contentBox = Components.utils.Sandbox('http://www.example.com'); 1.34 + let chromeBox = Components.utils.Sandbox(this); 1.35 + 1.36 + // Create an objects in this compartment, and one in each sandbox. We'll 1.37 + // refer to the objects as "mainObj", "contentObj", and "chromeObj", in 1.38 + // variable and property names. 1.39 + var mainObj = { name: "mainObj" }; 1.40 + Components.utils.evalInSandbox('var contentObj = { name: "contentObj" };', 1.41 + contentBox); 1.42 + Components.utils.evalInSandbox('var chromeObj = { name: "chromeObj" };', 1.43 + chromeBox); 1.44 + 1.45 + // Give each global a pointer to all the other globals' objects. 1.46 + contentBox.mainObj = chromeBox.mainObj = mainObj; 1.47 + var contentObj = chromeBox.contentObj = contentBox.contentObj; 1.48 + var chromeObj = contentBox.chromeObj = chromeBox.chromeObj; 1.49 + 1.50 + // First, a whole bunch of basic sanity checks, to ensure that JavaScript 1.51 + // evaluated in various scopes really does see the world the way this 1.52 + // test expects it to. 1.53 + 1.54 + // The objects appear as global variables in the sandbox, and as 1.55 + // the sandbox object's properties in chrome. 1.56 + do_check_true(Components.utils.evalInSandbox('mainObj', contentBox) 1.57 + === contentBox.mainObj); 1.58 + do_check_true(Components.utils.evalInSandbox('contentObj', contentBox) 1.59 + === contentBox.contentObj); 1.60 + do_check_true(Components.utils.evalInSandbox('chromeObj', contentBox) 1.61 + === contentBox.chromeObj); 1.62 + do_check_true(Components.utils.evalInSandbox('mainObj', chromeBox) 1.63 + === chromeBox.mainObj); 1.64 + do_check_true(Components.utils.evalInSandbox('contentObj', chromeBox) 1.65 + === chromeBox.contentObj); 1.66 + do_check_true(Components.utils.evalInSandbox('chromeObj', chromeBox) 1.67 + === chromeBox.chromeObj); 1.68 + 1.69 + // We (the main global) can see properties of all objects in all globals. 1.70 + do_check_true(contentBox.mainObj.name === "mainObj"); 1.71 + do_check_true(contentBox.contentObj.name === "contentObj"); 1.72 + do_check_true(contentBox.chromeObj.name === "chromeObj"); 1.73 + 1.74 + // chromeBox can see properties of all objects in all globals. 1.75 + do_check_eq(Components.utils.evalInSandbox('mainObj.name', chromeBox), 1.76 + 'mainObj'); 1.77 + do_check_eq(Components.utils.evalInSandbox('contentObj.name', chromeBox), 1.78 + 'contentObj'); 1.79 + do_check_eq(Components.utils.evalInSandbox('chromeObj.name', chromeBox), 1.80 + 'chromeObj'); 1.81 + 1.82 + // contentBox can see properties of the content object, but not of either 1.83 + // chrome object, because by default, content -> chrome wrappers hide all 1.84 + // object properties. 1.85 + do_check_eq(Components.utils.evalInSandbox('mainObj.name', contentBox), 1.86 + undefined); 1.87 + do_check_eq(Components.utils.evalInSandbox('contentObj.name', contentBox), 1.88 + 'contentObj'); 1.89 + do_check_eq(Components.utils.evalInSandbox('chromeObj.name', contentBox), 1.90 + undefined); 1.91 + 1.92 + // When viewing an object in compartment A from the vantage point of 1.93 + // compartment B, Debugger should give the same results as debuggee code 1.94 + // would. 1.95 + 1.96 + // Create a debugger, debugging our two sandboxes. 1.97 + let dbg = new Debugger; 1.98 + 1.99 + // Create Debugger.Object instances referring to the two sandboxes, as 1.100 + // seen from their own compartments. 1.101 + let contentBoxDO = dbg.addDebuggee(contentBox); 1.102 + let chromeBoxDO = dbg.addDebuggee(chromeBox); 1.103 + 1.104 + // Use Debugger to view the objects from contentBox. We should get the 1.105 + // same D.O instance from both getProperty and makeDebuggeeValue, and the 1.106 + // same property visibility we checked for above. 1.107 + let mainFromContentDO = contentBoxDO.getProperty('mainObj'); 1.108 + do_check_eq(mainFromContentDO, contentBoxDO.makeDebuggeeValue(mainObj)); 1.109 + do_check_eq(mainFromContentDO.getProperty('name'), undefined); 1.110 + do_check_eq(mainFromContentDO.unsafeDereference(), mainObj); 1.111 + 1.112 + let contentFromContentDO = contentBoxDO.getProperty('contentObj'); 1.113 + do_check_eq(contentFromContentDO, contentBoxDO.makeDebuggeeValue(contentObj)); 1.114 + do_check_eq(contentFromContentDO.getProperty('name'), 'contentObj'); 1.115 + do_check_eq(contentFromContentDO.unsafeDereference(), contentObj); 1.116 + 1.117 + let chromeFromContentDO = contentBoxDO.getProperty('chromeObj'); 1.118 + do_check_eq(chromeFromContentDO, contentBoxDO.makeDebuggeeValue(chromeObj)); 1.119 + do_check_eq(chromeFromContentDO.getProperty('name'), undefined); 1.120 + do_check_eq(chromeFromContentDO.unsafeDereference(), chromeObj); 1.121 + 1.122 + // Similarly, viewing from chromeBox. 1.123 + let mainFromChromeDO = chromeBoxDO.getProperty('mainObj'); 1.124 + do_check_eq(mainFromChromeDO, chromeBoxDO.makeDebuggeeValue(mainObj)); 1.125 + do_check_eq(mainFromChromeDO.getProperty('name'), 'mainObj'); 1.126 + do_check_eq(mainFromChromeDO.unsafeDereference(), mainObj); 1.127 + 1.128 + let contentFromChromeDO = chromeBoxDO.getProperty('contentObj'); 1.129 + do_check_eq(contentFromChromeDO, chromeBoxDO.makeDebuggeeValue(contentObj)); 1.130 + do_check_eq(contentFromChromeDO.getProperty('name'), 'contentObj'); 1.131 + do_check_eq(contentFromChromeDO.unsafeDereference(), contentObj); 1.132 + 1.133 + let chromeFromChromeDO = chromeBoxDO.getProperty('chromeObj'); 1.134 + do_check_eq(chromeFromChromeDO, chromeBoxDO.makeDebuggeeValue(chromeObj)); 1.135 + do_check_eq(chromeFromChromeDO.getProperty('name'), 'chromeObj'); 1.136 + do_check_eq(chromeFromChromeDO.unsafeDereference(), chromeObj); 1.137 +}