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>