tor-browser

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

test_sandbox_bindings.xhtml (14415B)


      1 <?xml version="1.0"?>
      2 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
      3 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
      4 <!--
      5 https://bugzilla.mozilla.org/show_bug.cgi?id=741267
      6 -->
      7 <window title="Mozilla Bug 741267"
      8        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      9  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
     10   <script type="application/javascript">
     11 
     12   
     13 </script>
     14  <iframe id="t"></iframe>
     15 
     16  <!-- test results are displayed in the html:body -->
     17  <body xmlns="http://www.w3.org/1999/xhtml">
     18  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=741267"
     19     target="_blank">Mozilla Bug 741267</a>
     20  </body>
     21 
     22  <!-- test code goes here -->
     23  <script type="application/javascript">
     24  <![CDATA[
     25 
     26  /** Test for Bug 741267 */
     27    function isXrayWrapper(x) {
     28      return Cu.isXrayWrapper(x);
     29    }
     30 
     31    function doTest() {
     32      var win = $("t").contentWindow;
     33      ok(isXrayWrapper(win),
     34         "We want to be testing things with an Xray as sandboxPrototype here");
     35 
     36      var sandbox = Cu.Sandbox(win, { sandboxPrototype: win });
     37 
     38      is(sandbox._content, undefined, "_content does nothing over Xray");
     39 
     40      try {
     41        var css = Cu.evalInSandbox("CSSStyleDeclaration", sandbox);
     42        is(String(css.prototype), "[object CSSStyleDeclaration]",
     43           "'CSSStyleDeclaration.prototype' in a sandbox should return the CSSStyleDeclaration interface prototype object");
     44      } catch (e) {
     45        ok(false, "'CSSStyleDeclaration' shouldn't throw in a sandbox");
     46      }
     47      try {
     48        var et = Cu.evalInSandbox("EventTarget", sandbox);
     49        ok(et, "'EventTarget' in a sandbox should return the EventTarget interface object");
     50        ok(isXrayWrapper(et), "Getting an interface object on an Xray wrapper should return an Xray wrapper");
     51      } catch (e) {
     52        ok(false, "'EventTarget' shouldn't throw in a sandbox");
     53      }
     54      try {
     55        var xhr = Cu.evalInSandbox("XMLHttpRequest.prototype", sandbox);
     56        ok(xhr, "'XMLHttpRequest.prototype' in a sandbox should return the XMLHttpRequest interface prototype object");
     57        ok(isXrayWrapper(xhr), "Getting an interface prototype object on an Xray wrapper should return an Xray wrapper");
     58        ok(isXrayWrapper(xhr.constructor), "Getting the constructor property on an Xray wrapper of an interface prototype object should return an Xray wrapper");
     59        isnot(Object.getOwnPropertyDescriptor(xhr, "send"), undefined,
     60              "We should claim to have a send() method");
     61        isnot(Object.keys(xhr).indexOf("responseType"), -1,
     62              "We should claim to have a responseType property");
     63        isnot(Object.getOwnPropertyNames(xhr).indexOf("open"), -1,
     64              "We should claim to have an open() method");
     65        isnot(Object.getOwnPropertyDescriptor(xhr, "constructor"), undefined,
     66              "We should claim to have a 'constructor' property");
     67      } catch (e) {
     68        ok(false, "'XMLHttpRequest.prototype' shouldn't throw in a sandbox");
     69      }
     70      try {
     71        var img = Cu.evalInSandbox("Image.prototype", sandbox);
     72        ok(img, "'Image.prototype' in a sandbox should return the interface prototype object");
     73        ok(isXrayWrapper(img), "Getting an interface prototype object on an Xray wrapper should return an Xray wrapper");
     74      } catch (e) {
     75        ok(false, "'Image.prototype' shouldn't throw in a sandbox");
     76      }
     77      try {
     78        var xhr = Cu.evalInSandbox("XMLHttpRequest", sandbox);
     79        xhr.prototype = "notok";
     80      } finally {
     81        isnot(xhr.prototype, "notok", "'XMLHttpRequest.prototype' should be readonly");
     82      }
     83      var constructorWritable = false;
     84      try {
     85        var xhr = Cu.evalInSandbox("XMLHttpRequest.prototype", sandbox);
     86        xhr.constructor = "ok";
     87        is(xhr.constructor, "ok", "'XMLHttpRequest.prototype.constructor' should be writeable");
     88      } catch (e) {
     89        ok(false, "'XMLHttpRequest.prototype.constructor' should be writeable");
     90      }
     91      try {
     92        var xhr = Cu.evalInSandbox("XMLHttpRequest", sandbox);
     93        is(String(xhr), String(XMLHttpRequest), "'XMLHttpRequest' in a sandbox should return the XMLHttpRequest interface object");
     94        ok(isXrayWrapper(xhr.prototype), "Getting the prototype property on an Xray wrapper of an interface object should return an Xray wrapper");
     95        isnot(Object.getOwnPropertyDescriptor(xhr, "UNSENT"), undefined,
     96              "We should claim to have an UNSENT constant");
     97        isnot(Object.keys(xhr).indexOf("OPENED"), -1,
     98              "We should claim to have an OPENED constant");
     99        isnot(Object.getOwnPropertyNames(xhr).indexOf("DONE"), -1,
    100              "We should claim to have a DONE constant");
    101        isnot(Object.getOwnPropertyDescriptor(xhr, "prototype"), undefined,
    102              "We should claim to have 'prototype' property");
    103      } catch (e) {
    104        ok(false, "'XMLHttpRequest' shouldn't throw in a sandbox");
    105      }
    106      try {
    107        var xhr = Cu.evalInSandbox("new XMLHttpRequest()", sandbox);
    108        is("" + xhr, new XMLHttpRequest() + "", "'new XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
    109      } catch (e) {
    110        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (1)");
    111      }
    112      try {
    113        var xhr = Cu.evalInSandbox("XMLHttpRequest.toString = function () { return 'Failed'; }; XMLHttpRequest;", sandbox);
    114        is(xhr.toString(), XMLHttpRequest + "", "XMLHttpRequest.toString in the sandbox should not override the native toString behaviour");
    115      } catch (e) {
    116        ok(false, "'XMLHttpRequest' shouldn't throw in a sandbox");
    117      }
    118      try {
    119        var xhr = Cu.evalInSandbox("XMLHttpRequest.prototype.toString = function () { return 'Failed'; }; new XMLHttpRequest();", sandbox);
    120        is(xhr.toString(), new XMLHttpRequest() + "", "XMLHttpRequest.prototype.toString in the sandbox should not override the native toString behaviour");
    121      } catch (e) {
    122        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (2)");
    123      }
    124 
    125      try {
    126        // have to run this test before document.defaultView.XMLHttpRequest
    127        // gets munged in the sandbox.
    128        var proto = Cu.evalInSandbox("XMLHttpRequest.prototype", sandbox);
    129        props = [];
    130        for (var i in proto) {
    131          props.push(i);
    132        }
    133        isnot(props.indexOf("dispatchEvent"), -1,
    134           "'dispatchEvent' property should be enumerable on XMLHttpRequest.prototype");
    135        props = Object.getOwnPropertyNames(proto);
    136        is(props.indexOf("dispatchEvent"), -1,
    137           "'dispatchEvent' is not an own property on XMLHttpRequest.prototype; it's on EventTarget.prototype")
    138      } catch (e) {
    139        ok(false, "XMLHttpRequest.prototype manipulation via an Xray shouldn't throw" + e);
    140      }
    141      try {
    142        Cu.evalInSandbox("XMLHttpRequest.prototype.a = 'expando a'", sandbox);
    143        Cu.evalInSandbox("XMLHttpRequest.prototype.b = 'expando b'", sandbox);
    144        Cu.evalInSandbox("XMLHttpRequest.prototype", sandbox).b = 'xrayexpando';
    145        var xhr = Cu.evalInSandbox("new XMLHttpRequest()", sandbox);
    146        is(xhr.a, undefined, "'XMLHttpRequest()' in a sandbox should not have expandos from inside the sandbox");
    147        is(xhr.b, "xrayexpando", "'new XMLHttpRequest()' in a sandbox should have Xray expandos");
    148      } catch (e) {
    149        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox");
    150      }
    151      try {
    152        Cu.evalInSandbox("document.defaultView.XMLHttpRequest = function() {};", sandbox);
    153        var win = Cu.evalInSandbox("document.defaultView", sandbox);
    154        var xhr = new win.XMLHttpRequest();
    155        is("" + xhr, new XMLHttpRequest() + "", "'new XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
    156      } catch (e) {
    157        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox");
    158      }
    159      try {
    160        var canvas = Cu.evalInSandbox("document.createElement('canvas').getContext('2d')", sandbox);
    161        is(canvas.DRAWWINDOW_DRAW_CARET, CanvasRenderingContext2D.DRAWWINDOW_DRAW_CARET, "Constants should be defined on DOM objects in a sandbox");
    162      } catch (e) {
    163        ok(false, "'document.createElement('canvas').getContext('2D')' shouldn't throw in a sandbox");
    164      }
    165      try {
    166        var classList = Cu.evalInSandbox("document.body.className = 'a b'; document.body.classList", sandbox);
    167        is(classList.toString(), "a b", "Stringifier should be called");
    168      } catch (e) {
    169        ok(false, "Stringifying shouldn't throw in a sandbox");
    170      }
    171      try {
    172        var ctx = Cu.evalInSandbox("var ctx = document.createElement('canvas').getContext('2d'); ctx.foopy = 5; ctx", sandbox);
    173        ok(!("foopy" in ctx), "We should have an Xray here");
    174        var data = ctx.createImageData(1, 1);
    175        for (var i = 0; i < data.data.length; ++i) {
    176          // Watch out for premultiplied bits... just set all the alphas to 255
    177          if (i % 4 == 3) {
    178            // Note - We need to waive Xrays here because indexed access on Typed
    179            // Arrays is forbidden over Xrays for performance reasons.
    180            Cu.waiveXrays(data.data)[i] = 255;
    181          } else {
    182            Cu.waiveXrays(data.data)[i] = i;
    183          }
    184        }
    185        ctx.putImageData(data, 0, 0);
    186        var data2 = ctx.getImageData(0, 0, 1, 1);
    187        is(data2.data.length, data.data.length, "Lengths must match");
    188        for (i = 0; i < data.data.length; ++i)
    189          is(Cu.waiveXrays(data.data)[i], Cu.waiveXrays(data2.data)[i], "Data at " + i + " should match");
    190      } catch (e) {
    191        ok(false, "Imagedata manipulation via an Xray shouldn't throw " + e);
    192      }
    193 
    194      try {
    195        var list = Cu.evalInSandbox("document.getElementsByTagName('*')", sandbox);
    196        props = [];
    197        for (var i in list) {
    198          props.push(i);
    199        }
    200        is(props.indexOf("constructor"), -1,
    201           "'constructor' property should not be enumerable on list object");
    202        props = Object.getOwnPropertyNames(list);
    203        is(props.indexOf("constructor"), -1,
    204           "'constructor' property should not be an own property name on list object");
    205      } catch (e) {
    206        ok(false, "NodeList.prototype manipulation via an Xray shouldn't throw" + e);
    207      }
    208 
    209      try {
    210        var proto = Cu.evalInSandbox("NodeList.prototype", sandbox);
    211        props = [];
    212        for (var i in proto) {
    213          props.push(i);
    214        }
    215        is(props.indexOf("constructor"), -1,
    216           "'constructor' property should not be enumerable on proto directly");
    217        props = Object.getOwnPropertyNames(proto);
    218        isnot(props.indexOf("constructor"), -1,
    219              "'constructor' property should be an own property name on proto");
    220      } catch (e) {
    221        ok(false, "NodeList.prototype manipulation via an Xray shouldn't throw" + e);
    222      }
    223 
    224      try {
    225        var url = Cu.evalInSandbox("URL", sandbox);
    226        for (var i in url) {
    227          url[i];
    228        }
    229        isnot(url.createObjectURL, undefined, "Should have a createObjectURL");
    230        ok(true, "We didn't crash!");
    231      } catch (e) {
    232        ok(false, "URL interface object manipulation via an Xray shouldn't throw" + e);
    233      }
    234 
    235      try {
    236        url.revokeObjectURL("");
    237      } catch (e) {
    238        // Just testing whether revokeObjectURL crashes us
    239      }
    240      ok(true, "We didn't crash!");
    241 
    242      // And now tests that don't use a window-associated sandbox
    243      sandbox = Cu.Sandbox(win.document.nodePrincipal,
    244                           { sandboxPrototype: win });
    245      try {
    246        var ws = Cu.evalInSandbox('var ws = new WebSocket("ws://example.org"); ws', sandbox);
    247        // Test that we actually got a WebSocket object, probably
    248        ok("bufferedAmount" in ws, "What is this object?");
    249      } catch (e) {
    250        ok(false, "Should be able to create a WebSocket in a sandbox " + e);
    251      }
    252      try {
    253        var es = Cu.evalInSandbox('var es = new EventSource("about:blank"); es', sandbox);
    254        // Test that we actually got a EventSource object, probably
    255        is(es.url, "about:blank", "What is this object?");
    256      } catch (e) {
    257        ok(false, "Should be able to create an EventSource in a sandbox " + e);
    258      }
    259 
    260      try {
    261        var nodeFilterIface = Cu.evalInSandbox(
    262          'NodeFilter.myExpando = "FAIL"; NodeFilter', sandbox);
    263        is(nodeFilterIface.myExpando, undefined,
    264           "Should have Xrays for callback interface objects");
    265      } catch (e) {
    266        ok(false, "Should be able to return NodeFilter from a sandbox " + e);
    267      }
    268 
    269      try {
    270        var eventCtor = Cu.evalInSandbox("Event", sandbox);
    271        var e = new eventCtor("test", { bubbles: true });
    272        is(e.bubbles, true, "Dictionary argument should work");
    273      } catch (e) {
    274        ok(false, "Should be able to construct my event " + e);
    275      }
    276 
    277      try {
    278        var elem = Cu.evalInSandbox('document.createElement("p")', sandbox);
    279        elem.expando = 5;
    280        elem.expando = 7;
    281        is(elem.expando, 7, "Should be able to set expandos on Xrays for DOM bindings");
    282        var doc = Cu.evalInSandbox('document', sandbox);
    283        doc.expando = 5;
    284        doc.expando = 7;
    285        is(doc.expando, 7, "Should be able to set expandos on Xrays for DOM bindings with named properties");
    286      } catch (e) {
    287        ok(false, "Setting expandos on Xrays shouldn't throw " + e);
    288      }
    289 
    290      // Test that binding a bareword window method produces something
    291      // which has a .call
    292      try {
    293        var binary = Cu.evalInSandbox(
    294          'btoa.bind(window).call(null, "foo")', sandbox);
    295        is(binary, "Zm9v", "Should get the right result from .call on bound btoa");
    296      } catch (e) {
    297        ok(false, ".call on bound btoa shouldn't throw " + e);
    298      }
    299 
    300      // Test that binding a bareword window method produces something
    301      // which has a .apply
    302      try {
    303        var binary = Cu.evalInSandbox(
    304          'btoa.bind(window).apply(null, ["foo"])', sandbox);
    305        is(binary, "Zm9v", "Should get the right result from .apply on bound btoa");
    306      } catch (e) {
    307        ok(false, ".apply on bound btoa shouldn't throw " + e);
    308      }
    309 
    310      SimpleTest.finish();
    311    }
    312 
    313    SimpleTest.waitForExplicitFinish();
    314    addLoadEvent(doTest);
    315  ]]>
    316  </script>
    317 </window>