tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }