tor-browser

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

test_exportFunction.js (5489B)


      1 function run_test() {
      2  var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true });
      3  var subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
      4  var subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
      5  var xorigsb = new Cu.Sandbox("http://test.com", { wantGlobalProperties: ["XMLHttpRequest"] });
      6 
      7  epsb.subsb = subsb;
      8  epsb.xorigsb = xorigsb;
      9  epsb.ok = ok;
     10  epsb.equal = equal;
     11  subsb.ok = ok;
     12  subsb.equal = equal;
     13 
     14  // Exporting should work if prinicipal of the source sandbox
     15  // subsumes the principal of the target sandbox.
     16  Cu.evalInSandbox("(" + function() {
     17    var wasCalled = false;
     18    this.funToExport = function(expectedThis, a, obj, native, mixed, callback) {
     19      equal(arguments.callee.length, 6);
     20      equal(a, 42);
     21      equal(obj, subsb.tobecloned);
     22      equal(obj.cloned, "cloned");
     23      equal(native, subsb.native);
     24      equal(expectedThis, this);
     25      equal(mixed.xrayed, subsb.xrayed);
     26      equal(mixed.xrayed2, subsb.xrayed2);
     27      if (typeof callback == 'function') {
     28        equal(typeof subsb.callback, 'function');
     29        equal(callback, subsb.callback);
     30        callback();
     31      }
     32      wasCalled = true;
     33    };
     34    this.checkIfCalled = function() {
     35      ok(wasCalled);
     36      wasCalled = false;
     37    }
     38    exportFunction(funToExport, subsb, { defineAs: "imported", allowCallbacks: true });
     39    exportFunction((x) => x, subsb, { defineAs: "echoAllowXO", allowCallbacks: true, allowCrossOriginArguments: true });
     40  }.toSource() + ")()", epsb);
     41 
     42  subsb.xrayed = Cu.evalInSandbox("(" + function () {
     43      return new XMLHttpRequest();
     44  }.toSource() + ")()", subsb2);
     45 
     46  // Exported function should be able to be call from the
     47  // target sandbox. Native arguments should be just wrapped
     48  // every other argument should be cloned.
     49  Cu.evalInSandbox("(" + function () {
     50    native = new XMLHttpRequest();
     51    xrayed2 = XPCNativeWrapper(new XMLHttpRequest());
     52    mixed = { xrayed: xrayed, xrayed2: xrayed2 };
     53    tobecloned = { cloned: "cloned" };
     54    invokedCallback = false;
     55    callback = function() { invokedCallback = true; };
     56    imported(this, 42, tobecloned, native, mixed, callback);
     57    equal(imported.length, 6);
     58    ok(invokedCallback);
     59  }.toSource() + ")()", subsb);
     60 
     61  // Invoking an exported function with cross-origin arguments should throw.
     62  subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb);
     63  try {
     64    Cu.evalInSandbox('imported(this, xoNative)', subsb);
     65    Assert.ok(false);
     66  } catch (e) {
     67    Assert.ok(/denied|insecure/.test(e));
     68  }
     69 
     70  // Callers can opt-out of the above.
     71  subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb);
     72  try {
     73    Assert.equal(Cu.evalInSandbox('echoAllowXO(xoNative)', subsb), subsb.xoNative);
     74    Assert.ok(true);
     75  } catch (e) {
     76    Assert.ok(false);
     77  }
     78 
     79  // Apply should work and |this| should carry over appropriately.
     80  Cu.evalInSandbox("(" + function() {
     81    var someThis = {};
     82    imported.apply(someThis, [someThis, 42, tobecloned, native, mixed]);
     83  }.toSource() + ")()", subsb);
     84 
     85  Cu.evalInSandbox("(" + function() {
     86    checkIfCalled();
     87  }.toSource() + ")()", epsb);
     88 
     89  // Exporting should throw if principal of the source sandbox does
     90  // not subsume the principal of the target.
     91  Cu.evalInSandbox("(" + function() {
     92    try{
     93      exportFunction(function() {}, this.xorigsb, { defineAs: "denied" });
     94      ok(false);
     95    } catch (e) {
     96      ok(e.toString().indexOf('Permission denied') > -1);
     97    }
     98  }.toSource() + ")()", epsb);
     99 
    100  // Exporting should throw if the principal of the source sandbox does
    101  // not subsume the principal of the function.
    102  epsb.xo_function = new xorigsb.Function();
    103  Cu.evalInSandbox("(" + function() {
    104    try{
    105      exportFunction(xo_function, this.subsb, { defineAs: "denied" });
    106      ok(false);
    107    } catch (e) {
    108      dump('Exception: ' + e);
    109      ok(e.toString().indexOf('Permission denied') > -1);
    110    }
    111  }.toSource() + ")()", epsb);
    112 
    113  // Let's create an object in the target scope and add privileged
    114  // function to it as a property.
    115  Cu.evalInSandbox("(" + function() {
    116    var newContentObject = createObjectIn(subsb, { defineAs: "importedObject" });
    117    exportFunction(funToExport, newContentObject, { defineAs: "privMethod" });
    118  }.toSource() + ")()", epsb);
    119 
    120  Cu.evalInSandbox("(" + function () {
    121    importedObject.privMethod(importedObject, 42, tobecloned, native, mixed);
    122  }.toSource() + ")()", subsb);
    123 
    124  Cu.evalInSandbox("(" + function() {
    125    checkIfCalled();
    126  }.toSource() + ")()", epsb);
    127 
    128  // exportFunction and createObjectIn should be available from Cu too.
    129  var newContentObject = Cu.createObjectIn(subsb, { defineAs: "importedObject2" });
    130  var wasCalled = false;
    131  Cu.exportFunction(function(arg) { wasCalled = arg.wasCalled; },
    132                    newContentObject, { defineAs: "privMethod" });
    133 
    134  Cu.evalInSandbox("(" + function () {
    135    importedObject2.privMethod({wasCalled: true});
    136  }.toSource() + ")()", subsb);
    137 
    138  // 3rd argument of exportFunction should be optional.
    139  Cu.evalInSandbox("(" + function() {
    140    subsb.imported2 = exportFunction(funToExport, subsb);
    141  }.toSource() + ")()", epsb);
    142 
    143  Cu.evalInSandbox("(" + function () {
    144    imported2(this, 42, tobecloned, native, mixed);
    145  }.toSource() + ")()", subsb);
    146 
    147  Cu.evalInSandbox("(" + function() {
    148    checkIfCalled();
    149  }.toSource() + ")()", epsb);
    150 
    151  Assert.ok(wasCalled);
    152 }