|
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"/> |
|
10 |
|
11 <iframe id="t"></iframe> |
|
12 |
|
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> |
|
18 |
|
19 <!-- test code goes here --> |
|
20 <script type="application/javascript"> |
|
21 <![CDATA[ |
|
22 |
|
23 /** Test for Bug 741267 **/ |
|
24 function isXrayWrapper(x) { |
|
25 return Components.utils.isXrayWrapper(x); |
|
26 } |
|
27 |
|
28 function doTest() { |
|
29 var win = $("t").contentWindow; |
|
30 var sandbox = Components.utils.Sandbox(win, { sandboxPrototype: win }); |
|
31 |
|
32 is(sandbox._content, undefined, "_content does nothing over Xray"); |
|
33 |
|
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 } |
|
121 |
|
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 } |
|
138 |
|
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 } |
|
179 |
|
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 } |
|
194 |
|
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 } |
|
209 |
|
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 } |
|
220 |
|
221 try { |
|
222 url.revokeObjectURL(""); |
|
223 } catch (e) { |
|
224 // Just testing whether revokeObjectURL crashes us |
|
225 } |
|
226 ok(true, "We didn't crash!"); |
|
227 |
|
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 } |
|
245 |
|
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 } |
|
254 |
|
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 } |
|
262 |
|
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 } |
|
275 |
|
276 SimpleTest.finish(); |
|
277 } |
|
278 |
|
279 SimpleTest.waitForExplicitFinish(); |
|
280 addLoadEvent(doTest); |
|
281 ]]> |
|
282 </script> |
|
283 </window> |