tor-browser

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

SpecialPowersSandbox.sys.mjs (3546B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * This modules handles creating and provisioning Sandboxes for
      7 * executing cross-process code from SpecialPowers. This allows all such
      8 * sandboxes to have a similar environment, and in particular allows
      9 * them to run test assertions in the target process and propagate
     10 * results back to the caller.
     11 */
     12 
     13 const lazy = {};
     14 
     15 ChromeUtils.defineESModuleGetters(lazy, {
     16  Assert: "resource://testing-common/Assert.sys.mjs",
     17 });
     18 
     19 // Note: When updating the set of globals exposed to sandboxes by
     20 // default, please also update the ESLint plugin rule defined in
     21 // import-content-task-globals.js.
     22 const SANDBOX_GLOBALS = [
     23  "Blob",
     24  "ChromeUtils",
     25  "FileReader",
     26  "TextDecoder",
     27  "TextEncoder",
     28  "URL",
     29 ];
     30 const EXTRA_IMPORTS = {
     31  EventUtils: "resource://testing-common/SpecialPowersEventUtils.sys.mjs",
     32 };
     33 
     34 let expectFail = false;
     35 function expectingFail(fn) {
     36  try {
     37    expectFail = true;
     38    fn();
     39  } finally {
     40    expectFail = false;
     41  }
     42 }
     43 
     44 export class SpecialPowersSandbox {
     45  constructor(name, reportCallback, opts = {}) {
     46    this.name = name;
     47    this.reportCallback = reportCallback;
     48 
     49    this._Assert = null;
     50 
     51    this.sandbox = Cu.Sandbox(
     52      Cu.getGlobalForObject({}),
     53      Object.assign(
     54        { wantGlobalProperties: SANDBOX_GLOBALS },
     55        opts.sandboxOptions
     56      )
     57    );
     58 
     59    for (let prop of ["assert", "Assert"]) {
     60      Object.defineProperty(this.sandbox, prop, {
     61        get: () => {
     62          return this.Assert;
     63        },
     64        enumerable: true,
     65        configurable: true,
     66      });
     67    }
     68 
     69    let imports = {
     70      ...EXTRA_IMPORTS,
     71      ...opts.imports,
     72    };
     73    // We explicitly want these directly in the sandbox, and we aren't going
     74    // to be using the globals within this file.
     75    // eslint-disable-next-line mozilla/lazy-getter-object-name
     76    ChromeUtils.defineESModuleGetters(this.sandbox, imports);
     77 
     78    // Note: When updating the set of globals exposed to sandboxes by
     79    // default, please also update the ESLint plugin rule defined in
     80    // import-content-task-globals.js.
     81    Object.assign(this.sandbox, {
     82      BrowsingContext,
     83      InspectorUtils,
     84      ok: (...args) => {
     85        this.Assert.ok(...args);
     86      },
     87      is: (...args) => {
     88        this.Assert.equal(...args);
     89      },
     90      isnot: (...args) => {
     91        this.Assert.notEqual(...args);
     92      },
     93      todo: (...args) => {
     94        expectingFail(() => this.Assert.ok(...args));
     95      },
     96      todo_is: (...args) => {
     97        expectingFail(() => this.Assert.equal(...args));
     98      },
     99      info: info => {
    100        this.reportCallback({ info });
    101      },
    102    });
    103  }
    104 
    105  get Assert() {
    106    if (!this._Assert) {
    107      this._Assert = new lazy.Assert((err, message, stack) => {
    108        this.report(err, message, stack);
    109      });
    110    }
    111    return this._Assert;
    112  }
    113 
    114  report(err, name, stack) {
    115    let diag;
    116    if (err) {
    117      diag =
    118        `got ${uneval(err.actual)}, expected ${uneval(err.expected)} ` +
    119        `(operator ${err.operator})`;
    120    }
    121 
    122    this.reportCallback({
    123      name,
    124      diag,
    125      passed: !err,
    126      stack: stack && stack.formattedStack,
    127      expectFail,
    128    });
    129  }
    130 
    131  execute(task, args, caller) {
    132    let func = Cu.evalInSandbox(
    133      `(${task})`,
    134      this.sandbox,
    135      undefined,
    136      caller.filename,
    137      caller.lineNumber
    138    );
    139    return func(...args);
    140  }
    141 }