Tue, 06 Jan 2015 21:39:09 +0100
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>