OLD | NEW |
1 (function() | 1 (function() |
2 { | 2 { |
3 let server = null; | 3 let server = null; |
4 let frame = null; | 4 let frame = null; |
5 let requestNotifier = null; | 5 let requestNotifier = null; |
6 | 6 |
7 module("Content policy", { | 7 module("Content policy", { |
8 setup: function() | 8 setup: function() |
9 { | 9 { |
10 prepareFilterComponents.call(this); | 10 prepareFilterComponents.call(this); |
11 preparePrefs.call(this); | 11 preparePrefs.call(this); |
12 | 12 |
13 server = new nsHttpServer(); | 13 server = new nsHttpServer(); |
14 server.start(1234); | 14 server.start(1234); |
15 | 15 |
16 frame = document.createElement("iframe"); | 16 frame = document.createElementNS("http://www.mozilla.org/keymaster/gatekee
per/there.is.only.xul", "iframe"); |
| 17 frame.setAttribute("type", "content"); |
17 frame.style.visibility = "collapse"; | 18 frame.style.visibility = "collapse"; |
18 document.body.appendChild(frame); | 19 document.body.appendChild(frame); |
19 | 20 |
20 requestNotifier = new RequestNotifier(window, onPolicyHit); | 21 requestNotifier = new RequestNotifier(frame.contentWindow, onPolicyHit); |
21 }, | 22 }, |
22 teardown: function() | 23 teardown: function() |
23 { | 24 { |
24 restoreFilterComponents.call(this); | 25 restoreFilterComponents.call(this); |
25 restorePrefs.call(this); | 26 restorePrefs.call(this); |
26 | 27 |
27 stop(); | 28 stop(); |
28 server.stop(function() | 29 server.stop(function() |
29 { | 30 { |
30 frame.parentElement.removeChild(frame); | 31 frame.parentElement.removeChild(frame); |
(...skipping 29 matching lines...) Expand all Loading... |
60 '<iframe src="data:text/html,%3Cinput%20type%3D%22image%22%20src%3D%22http
%3A%2F%2F127.0.0.1:1234%2Ftest.gif%22%3E"></iframe>', | 61 '<iframe src="data:text/html,%3Cinput%20type%3D%22image%22%20src%3D%22http
%3A%2F%2F127.0.0.1:1234%2Ftest.gif%22%3E"></iframe>', |
61 "http://127.0.0.1:1234/test.gif", "image", false, false | 62 "http://127.0.0.1:1234/test.gif", "image", false, false |
62 ], | 63 ], |
63 [ | 64 [ |
64 "HTML image button inside a nested frame", | 65 "HTML image button inside a nested frame", |
65 '<iframe src="data:text/html,%3Ciframe%20src%3D%22data%3Atext%2Fhtml%2C%25
3Cinput%2520type%253D%2522image%2522%2520src%253D%2522http%253A%252F%252F127.0.0
.1%3A1234%252Ftest.gif%2522%253E%22%3E%3C%2Fiframe%3E"></iframe>', | 66 '<iframe src="data:text/html,%3Ciframe%20src%3D%22data%3Atext%2Fhtml%2C%25
3Cinput%2520type%253D%2522image%2522%2520src%253D%2522http%253A%252F%252F127.0.0
.1%3A1234%252Ftest.gif%2522%253E%22%3E%3C%2Fiframe%3E"></iframe>', |
66 "http://127.0.0.1:1234/test.gif", "image", false, false | 67 "http://127.0.0.1:1234/test.gif", "image", false, false |
67 ], | 68 ], |
68 [ | 69 [ |
69 "Dynamically inserted image button", | 70 "Dynamically inserted image button", |
70 '<div id="insert"></div><script>window.addEventListener("DOMContentLoaded"
, function() { var div = document.getElementById("insert"); div.innerHTML = \'<i
nput type="image" id="image" src="test.gif">\'; var image = document.getElementB
yId("image"); image.onload = image.onerror = function () { parent.postMessage("l
oaded", "*"); }; }, false);<' + '/script>', | 71 '<div id="insert"></div>' + |
| 72 '<script>' + |
| 73 'window.addEventListener("DOMContentLoaded", function()' + |
| 74 '{' + |
| 75 'var div = document.getElementById("insert");' + |
| 76 'div.innerHTML = \'<input type="image" id="image" src="test.gif">\';'
+ |
| 77 'var image = document.getElementById("image");' + |
| 78 'image.onload = image.onerror = function ()' + |
| 79 '{' + |
| 80 'document.dispatchEvent(new CustomEvent("abp:frameready", {bubbles:
true}));' + |
| 81 '};' + |
| 82 '}, false);' + |
| 83 '</script>', |
71 "http://127.0.0.1:1234/test.gif", "image", false, true | 84 "http://127.0.0.1:1234/test.gif", "image", false, true |
72 ], | 85 ], |
73 [ | 86 [ |
74 "CSS background-image", | 87 "CSS background-image", |
75 '<div style="background-image: url(test.gif)"></div>', | 88 '<div style="background-image: url(test.gif)"></div>', |
76 "http://127.0.0.1:1234/test.gif", "image", false, false | 89 "http://127.0.0.1:1234/test.gif", "image", false, false |
77 ], | 90 ], |
78 [ | 91 [ |
79 "CSS cursor", | 92 "CSS cursor", |
80 '<div style="cursor: url(test.gif), pointer"></div>', | 93 '<div style="cursor: url(test.gif), pointer"></div>', |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 '<img src="redirect2.gif">', | 158 '<img src="redirect2.gif">', |
146 "http://127.0.0.1:1234/test.gif", "image", false, false | 159 "http://127.0.0.1:1234/test.gif", "image", false, false |
147 ], | 160 ], |
148 [ | 161 [ |
149 "CSS fonts", | 162 "CSS fonts", |
150 '<style type="text/css">@font-face { font-family: Test; src: url("test.otf
"); } html { font-family: Test; }</style>', | 163 '<style type="text/css">@font-face { font-family: Test; src: url("test.otf
"); } html { font-family: Test; }</style>', |
151 "http://127.0.0.1:1234/test.otf", "font", false, false | 164 "http://127.0.0.1:1234/test.otf", "font", false, false |
152 ], | 165 ], |
153 [ | 166 [ |
154 "XMLHttpRequest loading", | 167 "XMLHttpRequest loading", |
155 '<script>var request = new XMLHttpRequest();request.open("GET", "test.xml"
, false);request.send(null);</script>', | 168 '<script>' + |
| 169 'try' + |
| 170 '{' + |
| 171 'var request = new XMLHttpRequest();' + |
| 172 'request.open("GET", "test.xml", false);' + |
| 173 'request.send(null);' + |
| 174 '}' + |
| 175 'catch(e){}' + |
| 176 '</script>', |
156 "http://127.0.0.1:1234/test.xml", "xmlhttprequest", false, false | 177 "http://127.0.0.1:1234/test.xml", "xmlhttprequest", false, false |
157 ], | 178 ], |
158 [ | 179 [ |
159 "XML document loading", | 180 "XML document loading", |
160 '<script>var xmlDoc = document.implementation.createDocument(null, "root",
null);xmlDoc.async = false;xmlDoc.load("test.xml")</script>', | 181 '<script>' + |
| 182 'try' + |
| 183 '{' + |
| 184 'var xmlDoc = document.implementation.createDocument(null, "root", nul
l);' + |
| 185 'xmlDoc.async = false;' + |
| 186 'xmlDoc.load("test.xml");' + |
| 187 '}' + |
| 188 'catch(e){}' + |
| 189 '</script>', |
161 "http://127.0.0.1:1234/test.xml", "xmlhttprequest", false, false | 190 "http://127.0.0.1:1234/test.xml", "xmlhttprequest", false, false |
162 ], | 191 ], |
163 [ | 192 [ |
164 "Web worker", | 193 "Web worker", |
165 '<script>try { var worker = new Worker("test.js"); worker.onerror = functi
on() { parent.postMessage("loaded", "*"); }; } catch (e) { parent.postMessage("e
rror", "*"); }</script>', | 194 '<script>' + |
| 195 'var e = new CustomEvent(\'abp:frameready\', {bubbles: true});' + |
| 196 'try' + |
| 197 '{' + |
| 198 'var worker = new Worker("test.js");' + |
| 199 'worker.onerror = function(event)' + |
| 200 '{' + |
| 201 'event.preventDefault();' + |
| 202 'document.dispatchEvent(e);' + |
| 203 '};' + |
| 204 '}' + |
| 205 'catch (x)' + |
| 206 '{' + |
| 207 'document.dispatchEvent(e);' + |
| 208 '}' + |
| 209 '</script>', |
166 "http://127.0.0.1:1234/test.js", "script", false, true | 210 "http://127.0.0.1:1234/test.js", "script", false, true |
167 ], | 211 ], |
168 ]; | 212 ]; |
169 | 213 |
170 if (window.navigator.mimeTypes["application/x-shockwave-flash"] && window.navi
gator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) | 214 if (window.navigator.mimeTypes["application/x-shockwave-flash"] && window.navi
gator.mimeTypes["application/x-shockwave-flash"].enabledPlugin) |
171 { | 215 { |
172 tests.push([ | 216 tests.push([ |
173 "HTML embed (Flash)", | 217 "HTML embed (Flash)", |
174 '<embed type="application/x-shockwave-flash" src="test.swf"></embed>' + | 218 '<embed type="application/x-shockwave-flash" src="test.swf"></embed>' + |
175 '<script>var r = new XMLHttpRequest();r.open("GET", "", false);r.send(nu
ll);</script>', | 219 '<script>var r = new XMLHttpRequest();r.open("GET", "", false);r.send(nu
ll);</script>', |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 if (policyHits.length > 0) | 260 if (policyHits.length > 0) |
217 { | 261 { |
218 // Ignore duplicate policy calls (possible due to prefetching) | 262 // Ignore duplicate policy calls (possible due to prefetching) |
219 let [prevWnd, prevNode, prevItem] = policyHits[policyHits.length - 1]; | 263 let [prevWnd, prevNode, prevItem] = policyHits[policyHits.length - 1]; |
220 if (prevWnd == wnd && prevItem.location == item.location && prevItem.type
== item.type && prevItem.docDomain == item.docDomain) | 264 if (prevWnd == wnd && prevItem.location == item.location && prevItem.type
== item.type && prevItem.docDomain == item.docDomain) |
221 policyHits.pop(); | 265 policyHits.pop(); |
222 } | 266 } |
223 policyHits.push([wnd, node, item]); | 267 policyHits.push([wnd, node, item]); |
224 } | 268 } |
225 | 269 |
226 function runTest([name, body, expectedURL, expectedType, expectedThirdParty, w
aitForMessage], stage) | 270 function runTest([name, body, expectedURL, expectedType, expectedThirdParty, e
xplicitEvent], stage) |
227 { | 271 { |
228 defaultMatcher.clear(); | 272 defaultMatcher.clear(); |
229 | 273 |
230 if (stage > 1) | 274 if (stage > 1) |
231 defaultMatcher.add(Filter.fromText(expectedURL)); | 275 defaultMatcher.add(Filter.fromText(expectedURL)); |
232 if (stage == 3) | 276 if (stage == 3) |
233 defaultMatcher.add(Filter.fromText("@@||127.0.0.1:1234/test|$document")); | 277 defaultMatcher.add(Filter.fromText("@@||127.0.0.1:1234/test|$document")); |
234 if (stage == 4) | 278 if (stage == 4) |
235 defaultMatcher.add(Filter.fromText("@@||127.0.0.1:1234/test|$~document")); | 279 defaultMatcher.add(Filter.fromText("@@||127.0.0.1:1234/test|$~document")); |
236 | 280 |
| 281 if (!explicitEvent) |
| 282 { |
| 283 if (body.indexOf("2000/svg") >= 0) |
| 284 { |
| 285 // SVG image: add an onload attribute to the document element |
| 286 body = body.replace(/(<svg\b)/, '$1 onload="this.dispatchEvent(new Custo
mEvent(\'abp:frameready\', {bubbles: true}));"'); |
| 287 } |
| 288 else |
| 289 { |
| 290 // HTML data: wrap it into a <body> tag |
| 291 body = '<body onload="this.dispatchEvent(new CustomEvent(\'abp:frameread
y\', {bubbles: true}));">' + body + '</body>'; |
| 292 } |
| 293 } |
| 294 |
237 let serverHit = false; | 295 let serverHit = false; |
238 server.registerPathHandler("/test", function(metadata, response) | 296 server.registerPathHandler("/test", function(metadata, response) |
239 { | 297 { |
240 response.setStatusLine("1.1", "200", "OK"); | 298 response.setStatusLine("1.1", "200", "OK"); |
241 | 299 |
242 let contentType = "text/html"; | 300 let contentType = "text/html"; |
243 if (body.indexOf("2000/svg") >= 0) | 301 if (body.indexOf("2000/svg") >= 0) |
244 contentType = "image/svg+xml"; | 302 contentType = "image/svg+xml"; |
245 response.setHeader("Content-Type", contentType + "; charset=utf-8"); | 303 response.setHeader("Content-Type", contentType + "; charset=utf-8"); |
246 | 304 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 345 |
288 equal(actualStatus, expectedStatus, "Request blocked"); | 346 equal(actualStatus, expectedStatus, "Request blocked"); |
289 equal(item.typeDescr.toLowerCase(), expectedType, "Request type"); | 347 equal(item.typeDescr.toLowerCase(), expectedType, "Request type"); |
290 equal(item.thirdParty, expectedThirdParty, "Third-party flag"); | 348 equal(item.thirdParty, expectedThirdParty, "Third-party flag"); |
291 equal(item.docDomain, "127.0.0.1", "Document domain"); | 349 equal(item.docDomain, "127.0.0.1", "Document domain"); |
292 } | 350 } |
293 } | 351 } |
294 server.registerPathHandler(expectedURL.replace(/http:\/\/[^\/]+/, ""), nul
l); | 352 server.registerPathHandler(expectedURL.replace(/http:\/\/[^\/]+/, ""), nul
l); |
295 equal(serverHit, expectedStatus == "allowed", "Request received by server"
); | 353 equal(serverHit, expectedStatus == "allowed", "Request received by server"
); |
296 | 354 |
297 window.removeEventListener("message", callback, false); | 355 frame.removeEventListener("abp:frameready", callback, false); |
298 frame.removeEventListener("load", callback, false); | |
299 | 356 |
300 start(); | 357 start(); |
301 }; | 358 }; |
302 frame.contentWindow.location.href = "http://127.0.0.1:1234/test"; | 359 frame.addEventListener("abp:frameready", callback, false, true); |
303 | 360 frame.setAttribute("src", "http://127.0.0.1:1234/test"); |
304 if (waitForMessage) | |
305 window.addEventListener("message", callback, false, true); | |
306 else | |
307 frame.addEventListener("load", callback, false); | |
308 } | 361 } |
309 | 362 |
310 let stageDescriptions = { | 363 let stageDescriptions = { |
311 1: "running without filters", | 364 1: "running without filters", |
312 2: "running with filter %S", | 365 2: "running with filter %S", |
313 3: "running with filter %S and site exception", | 366 3: "running with filter %S and site exception", |
314 4: "running with filter %S and exception not applicable to sites", | 367 4: "running with filter %S and exception not applicable to sites", |
315 }; | 368 }; |
316 | 369 |
317 for (let test = 0; test < tests.length; test++) | 370 for (let test = 0; test < tests.length; test++) |
318 { | 371 { |
319 let [name, body, expectedURL, expectedType, expectedDomain, expectedThirdPar
ty] = tests[test]; | 372 let [name, body, expectedURL, expectedType, expectedDomain, expectedThirdPar
ty] = tests[test]; |
320 for (let stage = 1; stage in stageDescriptions; stage++) | 373 for (let stage = 1; stage in stageDescriptions; stage++) |
321 { | 374 { |
322 let stageDescription = stageDescriptions[stage]; | 375 let stageDescription = stageDescriptions[stage]; |
323 if (stageDescription.indexOf("%S") >= 0) | 376 if (stageDescription.indexOf("%S") >= 0) |
324 stageDescription = stageDescription.replace("%S", expectedURL); | 377 stageDescription = stageDescription.replace("%S", expectedURL); |
325 | 378 |
326 asyncTest(name + " (" + stageDescription + ")", runTest.bind(null, tests[t
est], stage)); | 379 asyncTest(name + " (" + stageDescription + ")", runTest.bind(null, tests[t
est], stage)); |
327 } | 380 } |
328 } | 381 } |
329 })(); | 382 })(); |
OLD | NEW |