dom/tests/mochitest/chrome/test_sandbox_bindings.xul

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial