dom/tests/mochitest/chrome/test_sandbox_bindings.xul

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/tests/mochitest/chrome/test_sandbox_bindings.xul	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,283 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
     1.6 +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
     1.7 +<!--
     1.8 +https://bugzilla.mozilla.org/show_bug.cgi?id=741267
     1.9 +-->
    1.10 +<window title="Mozilla Bug 741267"
    1.11 +        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    1.12 +  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
    1.13 +
    1.14 +  <iframe id="t"></iframe>
    1.15 +
    1.16 +  <!-- test results are displayed in the html:body -->
    1.17 +  <body xmlns="http://www.w3.org/1999/xhtml">
    1.18 +  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=741267"
    1.19 +     target="_blank">Mozilla Bug 741267</a>
    1.20 +  </body>
    1.21 +
    1.22 +  <!-- test code goes here -->
    1.23 +  <script type="application/javascript">
    1.24 +  <![CDATA[
    1.25 +
    1.26 +  /** Test for Bug 741267 **/
    1.27 +    function isXrayWrapper(x) {
    1.28 +      return Components.utils.isXrayWrapper(x);
    1.29 +    }
    1.30 +
    1.31 +    function doTest() {
    1.32 +      var win = $("t").contentWindow;
    1.33 +      var sandbox = Components.utils.Sandbox(win, { sandboxPrototype: win });
    1.34 +
    1.35 +      is(sandbox._content, undefined, "_content does nothing over Xray");
    1.36 +
    1.37 +      try {
    1.38 +        var css = Components.utils.evalInSandbox("CSSStyleDeclaration", sandbox);
    1.39 +        is(css.prototype, "[object XrayWrapper [object CSSStyleDeclarationPrototype]]", "'CSSStyleDeclaration.prototype' in a sandbox should return the CSSStyleDeclaration interface prototype object");
    1.40 +      } catch (e) {
    1.41 +        ok(false, "'CSSStyleDeclaration' shouldn't throw in a sandbox");
    1.42 +      }
    1.43 +      try {
    1.44 +        var et = Components.utils.evalInSandbox("EventTarget", sandbox);
    1.45 +        ok(et, "'EventTarget' in a sandbox should return the EventTarget interface object");
    1.46 +        ok(isXrayWrapper(et), "Getting an interface object on an Xray wrapper should return an Xray wrapper");
    1.47 +      } catch (e) {
    1.48 +        ok(false, "'EventTarget' shouldn't throw in a sandbox");
    1.49 +      }
    1.50 +      try {
    1.51 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox);
    1.52 +        ok(xhr, "'XMLHttpRequest.prototype' in a sandbox should return the XMLHttpRequest interface prototype object");
    1.53 +        ok(isXrayWrapper(xhr), "Getting an interface prototype object on an Xray wrapper should return an Xray wrapper");
    1.54 +        ok(isXrayWrapper(xhr.constructor), "Getting the constructor property on an Xray wrapper of an interface prototype object should return an Xray wrapper");
    1.55 +        isnot(Object.getOwnPropertyDescriptor(xhr, "send"), undefined,
    1.56 +              "We should claim to have a send() method");
    1.57 +        isnot(Object.keys(xhr).indexOf("responseType"), -1,
    1.58 +              "We should claim to have a responseType property");
    1.59 +        isnot(Object.getOwnPropertyNames(xhr).indexOf("open"), -1,
    1.60 +              "We should claim to have an open() method");
    1.61 +        isnot(Object.getOwnPropertyDescriptor(xhr, "constructor"), undefined,
    1.62 +              "We should claim to have a 'constructor' property");
    1.63 +      } catch (e) {
    1.64 +        ok(false, "'XMLHttpRequest.prototype' shouldn't throw in a sandbox");
    1.65 +      }
    1.66 +      try {
    1.67 +        var img = Components.utils.evalInSandbox("Image.prototype", sandbox);
    1.68 +        ok(img, "'Image.prototype' in a sandbox should return the interface prototype object");
    1.69 +        ok(isXrayWrapper(img), "Getting an interface prototype object on an Xray wrapper should return an Xray wrapper");
    1.70 +      } catch (e) {
    1.71 +        ok(false, "'Image.prototype' shouldn't throw in a sandbox");
    1.72 +      }
    1.73 +      try {
    1.74 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
    1.75 +        xhr.prototype = false;
    1.76 +      } catch (e) {
    1.77 +        ok(true, "'XMLHttpRequest.prototype' should be readonly");
    1.78 +      }
    1.79 +      try {
    1.80 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
    1.81 +        delete xhr.prototype;
    1.82 +      } catch (e) {
    1.83 +        ok(true, "'XMLHttpRequest.prototype' should be permanent");
    1.84 +      }
    1.85 +      try {
    1.86 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox);
    1.87 +        xhr.constructor = "ok";
    1.88 +      } catch (e) {
    1.89 +        is(xhr.constructor, "ok", "'XMLHttpRequest.prototype.constructor' should be writeable");
    1.90 +      }
    1.91 +      try {
    1.92 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox);
    1.93 +        delete xhr.constructor;
    1.94 +      } catch (e) {
    1.95 +        is(xhr.constructor, undefined, "'XMLHttpRequest.prototype.constructor' should be permanent");
    1.96 +      }
    1.97 +      try {
    1.98 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest", sandbox);
    1.99 +        is(xhr, "[object XrayWrapper " + XMLHttpRequest + "]", "'XMLHttpRequest' in a sandbox should return the XMLHttpRequest interface object");
   1.100 +        ok(isXrayWrapper(xhr.prototype), "Getting the prototype property on an Xray wrapper of an interface object should return an Xray wrapper");
   1.101 +        isnot(Object.getOwnPropertyDescriptor(xhr, "UNSENT"), undefined,
   1.102 +              "We should claim to have an UNSENT constant");
   1.103 +        isnot(Object.keys(xhr).indexOf("OPENED"), -1,
   1.104 +              "We should claim to have an OPENED constant");
   1.105 +        isnot(Object.getOwnPropertyNames(xhr).indexOf("DONE"), -1,
   1.106 +              "We should claim to have a DONE constant");
   1.107 +        isnot(Object.getOwnPropertyDescriptor(xhr, "prototype"), undefined,
   1.108 +              "We should claim to have 'prototype' property");
   1.109 +      } catch (e) {
   1.110 +        ok(false, "'XMLHttpRequest' shouldn't throw in a sandbox");
   1.111 +      }
   1.112 +      try {
   1.113 +        var xhr = Components.utils.evalInSandbox("new XMLHttpRequest()", sandbox);
   1.114 +        is("" + xhr, "[object XrayWrapper " + new XMLHttpRequest() + "]", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
   1.115 +      } catch (e) {
   1.116 +        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (1)");
   1.117 +      }
   1.118 +      try {
   1.119 +        var xhr = Components.utils.evalInSandbox("XMLHttpRequest.prototype.toString = function () { return 'Failed'; }; new XMLHttpRequest();", sandbox);
   1.120 +        is(xhr.toString(), "[object XrayWrapper " + new XMLHttpRequest() + "]", "XMLHttpRequest.prototype.toString in the sandbox should not override the native toString behaviour");
   1.121 +      } catch (e) {
   1.122 +        ok(false, "'new XMLHttpRequest()' shouldn't throw in a sandbox (2)");
   1.123 +      }
   1.124 +
   1.125 +      try {
   1.126 +        // have to run this test before document.defaultView.XMLHttpRequest
   1.127 +        // gets munged in the sandbox.
   1.128 +        var proto = Components.utils.evalInSandbox("XMLHttpRequest.prototype", sandbox);
   1.129 +        props = [];
   1.130 +        for (var i in proto) {
   1.131 +          props.push(i);
   1.132 +        }
   1.133 +        isnot(props.indexOf("dispatchEvent"), -1,
   1.134 +           "'dispatchEvent' property should be enumerable on XMLHttpRequest.prototype");
   1.135 +        props = Object.getOwnPropertyNames(proto);
   1.136 +        is(props.indexOf("dispatchEvent"), -1,
   1.137 +           "'dispatchEvent' is not an own property on XMLHttpRequest.prototype; it's on EventTarget.prototype")
   1.138 +      } catch (e) {
   1.139 +        ok(false, "XMLHttpRequest.prototype manipulation via an Xray shouldn't throw" + e);
   1.140 +      }
   1.141 +
   1.142 +      try {
   1.143 +        Components.utils.evalInSandbox("document.defaultView.XMLHttpRequest = function() {};", sandbox);
   1.144 +        var win = Components.utils.evalInSandbox("document.defaultView", sandbox);
   1.145 +        var xhr = new win.XMLHttpRequest();
   1.146 +        is("" + xhr, "[object XrayWrapper " + new XMLHttpRequest() + "]", "'XMLHttpRequest()' in a sandbox should create an XMLHttpRequest object");
   1.147 +      } catch (e) {
   1.148 +        ok(false, "'XMLHttpRequest()' shouldn't throw in a sandbox");
   1.149 +      }
   1.150 +      try {
   1.151 +        var canvas = Components.utils.evalInSandbox("document.createElement('canvas').getContext('2d')", sandbox);
   1.152 +        is(canvas.DRAWWINDOW_DRAW_CARET, CanvasRenderingContext2D.DRAWWINDOW_DRAW_CARET, "Constants should be defined on DOM objects in a sandbox");
   1.153 +      } catch (e) {
   1.154 +        ok(false, "'document.createElement('canvas').getContext('2D')' shouldn't throw in a sandbox");
   1.155 +      }
   1.156 +      try {
   1.157 +        var classList = Components.utils.evalInSandbox("document.body.className = 'a b'; document.body.classList", sandbox);
   1.158 +        is(classList.toString(), "a b", "Stringifier should be called");
   1.159 +      } catch (e) {
   1.160 +        ok(false, "'document.createElement('canvas').getContext('2D')' shouldn't throw in a sandbox");
   1.161 +      }
   1.162 +      try {
   1.163 +        var ctx = Components.utils.evalInSandbox("var ctx = document.createElement('canvas').getContext('2d'); ctx.foopy = 5; ctx", sandbox);
   1.164 +        ok(!("foopy" in ctx), "We should have an Xray here");
   1.165 +        var data = ctx.createImageData(1, 1);
   1.166 +        for (var i = 0; i < data.data.length; ++i) {
   1.167 +          // Watch out for premultiplied bits... just set all the alphas to 255
   1.168 +          if (i % 4 == 3) {
   1.169 +            data.data[i] = 255;
   1.170 +          } else {
   1.171 +            data.data[i] = i;
   1.172 +          }
   1.173 +        }
   1.174 +        ctx.putImageData(data, 0, 0);
   1.175 +        var data2 = ctx.getImageData(0, 0, 1, 1);
   1.176 +        is(data2.data.length, data.data.length, "Lengths must match");
   1.177 +        for (i = 0; i < data.data.length; ++i)
   1.178 +          is(data.data[i], data2.data[i], "Data at " + i + " should match");
   1.179 +      } catch (e) {
   1.180 +        ok(false, "Imagedata manipulation via an Xray shouldn't throw " + e);
   1.181 +      }
   1.182 +
   1.183 +      try {
   1.184 +        var list = Components.utils.evalInSandbox("document.getElementsByTagName('*')", sandbox);
   1.185 +        props = [];
   1.186 +        for (var i in list) {
   1.187 +          props.push(i);
   1.188 +        }
   1.189 +        is(props.indexOf("constructor"), -1,
   1.190 +           "'constructor' property should not be enumerable on list object");
   1.191 +        props = Object.getOwnPropertyNames(list);
   1.192 +        is(props.indexOf("constructor"), -1,
   1.193 +           "'constructor' property should not be an own property name on list object");
   1.194 +      } catch (e) {
   1.195 +        ok(false, "NodeList.prototype manipulation via an Xray shouldn't throw" + e);
   1.196 +      }
   1.197 +
   1.198 +      try {
   1.199 +        var proto = Components.utils.evalInSandbox("NodeList.prototype", sandbox);
   1.200 +        props = [];
   1.201 +        for (var i in proto) {
   1.202 +          props.push(i);
   1.203 +        }
   1.204 +        is(props.indexOf("constructor"), -1,
   1.205 +           "'constructor' property should not be enumerable on proto directly");
   1.206 +        props = Object.getOwnPropertyNames(proto);
   1.207 +        isnot(props.indexOf("constructor"), -1,
   1.208 +              "'constructor' property should be an own property name on proto");
   1.209 +      } catch (e) {
   1.210 +        ok(false, "NodeList.prototype manipulation via an Xray shouldn't throw" + e);
   1.211 +      }
   1.212 +
   1.213 +      try {
   1.214 +        var url = Components.utils.evalInSandbox("URL", sandbox);
   1.215 +        for (var i in url) {
   1.216 +          url[i];
   1.217 +        }
   1.218 +        isnot(url.createObjectURL, undefined, "Should have a createObjectURL");
   1.219 +        ok(true, "We didn't crash!");
   1.220 +      } catch (e) {
   1.221 +        ok(false, "URL interface object manipulation via an Xray shouldn't throw" + e);
   1.222 +      }
   1.223 +
   1.224 +      try {
   1.225 +        url.revokeObjectURL("");
   1.226 +      } catch (e) {
   1.227 +        // Just testing whether revokeObjectURL crashes us
   1.228 +      }
   1.229 +      ok(true, "We didn't crash!");
   1.230 +
   1.231 +      // And now tests that don't use a window-associated sandbox
   1.232 +      sandbox = Components.utils.Sandbox(win.document.nodePrincipal,
   1.233 +                                         { sandboxPrototype: win });
   1.234 +      try {
   1.235 +        var ws = Components.utils.evalInSandbox('var ws = new WebSocket("ws://example.org"); ws', sandbox);
   1.236 +        // Test that we actually got a WebSocket object, probably
   1.237 +        ok("bufferedAmount" in ws, "What is this object?");
   1.238 +      } catch (e) {
   1.239 +        ok(false, "Should be able to create a WebSocket in a sandbox " + e);
   1.240 +      }
   1.241 +      try {
   1.242 +        var es = Components.utils.evalInSandbox('var es = new EventSource("about:blank"); es', sandbox);
   1.243 +        // Test that we actually got a EventSource object, probably
   1.244 +        is(es.url, "about:blank", "What is this object?");
   1.245 +      } catch (e) {
   1.246 +        ok(false, "Should be able to create an EventSource in a sandbox " + e);
   1.247 +      }
   1.248 +
   1.249 +      try {
   1.250 +        var nodeFilterIface = Components.utils.evalInSandbox(
   1.251 +          'NodeFilter.myExpando = "FAIL"; NodeFilter', sandbox);
   1.252 +        is(nodeFilterIface.myExpando, undefined,
   1.253 +           "Should have Xrays for callback interface objects");
   1.254 +      } catch (e) {
   1.255 +        ok(false, "Should be able to return NodeFilter from a sandbox " + e);
   1.256 +      }
   1.257 +
   1.258 +      try {
   1.259 +        var eventCtor = Components.utils.evalInSandbox("Event", sandbox);
   1.260 +        var e = new eventCtor("test", { bubbles: true });
   1.261 +        is(e.bubbles, true, "Dictionary argument should work");
   1.262 +      } catch (e) {
   1.263 +        ok(false, "Should be able to construct my event " + e);
   1.264 +      }
   1.265 +
   1.266 +      try {
   1.267 +        var elem = Components.utils.evalInSandbox('document.createElement("p")', sandbox);
   1.268 +        elem.expando = 5;
   1.269 +        elem.expando = 7;
   1.270 +        is(elem.expando, 7, "Should be able to set expandos on Xrays for DOM bindings");
   1.271 +        var doc = Components.utils.evalInSandbox('document', sandbox);
   1.272 +        doc.expando = 5;
   1.273 +        doc.expando = 7;
   1.274 +        is(doc.expando, 7, "Should be able to set expandos on Xrays for DOM bindings with named properties");
   1.275 +      } catch (e) {
   1.276 +        ok(false, "Setting expandos on Xrays shouldn't throw " + e);
   1.277 +      }
   1.278 +
   1.279 +      SimpleTest.finish();
   1.280 +    }
   1.281 +
   1.282 +    SimpleTest.waitForExplicitFinish();
   1.283 +    addLoadEvent(doTest);
   1.284 +  ]]>
   1.285 +  </script>
   1.286 +</window>

mercurial