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