Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | <?xml version="1.0"?> |
michael@0 | 2 | <?xml-stylesheet type="text/css" href="chrome://global/skin"?> |
michael@0 | 3 | <?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> |
michael@0 | 4 | <!-- Any copyright is dedicated to the Public Domain. |
michael@0 | 5 | http://creativecommons.org/publicdomain/zero/1.0/ --> |
michael@0 | 6 | <!-- |
michael@0 | 7 | https://bugzilla.mozilla.org/show_bug.cgi?id=762993 |
michael@0 | 8 | --> |
michael@0 | 9 | <window title="Mozilla Bug 762993" |
michael@0 | 10 | xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
michael@0 | 11 | onload="run_next_test();"> |
michael@0 | 12 | <script type="application/javascript" |
michael@0 | 13 | src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> |
michael@0 | 14 | |
michael@0 | 15 | <!-- test results are displayed in the html:body --> |
michael@0 | 16 | <body xmlns="http://www.w3.org/1999/xhtml"> |
michael@0 | 17 | <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=762993" |
michael@0 | 18 | target="_blank">Mozilla Bug 762993</a> |
michael@0 | 19 | </body> |
michael@0 | 20 | |
michael@0 | 21 | <!-- test code goes here --> |
michael@0 | 22 | <script type="application/javascript;version=1.8"> |
michael@0 | 23 | <![CDATA[ |
michael@0 | 24 | |
michael@0 | 25 | /** Test for Bug 762993 **/ |
michael@0 | 26 | |
michael@0 | 27 | "use strict"; |
michael@0 | 28 | |
michael@0 | 29 | SimpleTest.expectAssertions(1); |
michael@0 | 30 | |
michael@0 | 31 | SimpleTest.waitForExplicitFinish(); |
michael@0 | 32 | |
michael@0 | 33 | const Cc = Components.classes; |
michael@0 | 34 | const Ci = Components.interfaces; |
michael@0 | 35 | const Cu = Components.utils; |
michael@0 | 36 | |
michael@0 | 37 | const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager); |
michael@0 | 38 | |
michael@0 | 39 | const TEST_URL_1 = "https://example.com/"; |
michael@0 | 40 | // No trailing slash plus port to test normalization |
michael@0 | 41 | const TEST_URL_2 = "https://example.com:443"; |
michael@0 | 42 | |
michael@0 | 43 | const TEST_BASE = "http://mochi.test:8888/chrome/toolkit/identity/tests/chrome/" |
michael@0 | 44 | const STATE_URL = TEST_BASE + "sandbox_content.sjs" |
michael@0 | 45 | |
michael@0 | 46 | Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
michael@0 | 47 | Cu.import("resource://gre/modules/Services.jsm"); |
michael@0 | 48 | |
michael@0 | 49 | Services.prefs.setBoolPref("toolkit.identity.debug", true); |
michael@0 | 50 | |
michael@0 | 51 | XPCOMUtils.defineLazyModuleGetter(this, "Sandbox", |
michael@0 | 52 | "resource://gre/modules/identity/Sandbox.jsm"); |
michael@0 | 53 | |
michael@0 | 54 | function check_sandbox(aSandbox, aURL) { |
michael@0 | 55 | ok(aSandbox.id > 0, "valid ID"); |
michael@0 | 56 | is(aSandbox._url, aURL, "matching URL (with normalization)"); |
michael@0 | 57 | isnot(aSandbox._frame, null, "frame"); |
michael@0 | 58 | isnot(aSandbox._container, null, "container"); |
michael@0 | 59 | let docPrincipal = aSandbox._frame.contentDocument.nodePrincipal; |
michael@0 | 60 | is(secMan.isSystemPrincipal(docPrincipal), false, |
michael@0 | 61 | "principal must not be system"); |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | /** |
michael@0 | 65 | * Free the sandbox and make sure all properties that are not booleans, |
michael@0 | 66 | * functions or numbers were freed. |
michael@0 | 67 | */ |
michael@0 | 68 | function free_and_check_sandbox(aSandbox) { |
michael@0 | 69 | SimpleTest.executeSoon(function() { |
michael@0 | 70 | aSandbox.free(); |
michael@0 | 71 | |
michael@0 | 72 | for(let prop in aSandbox) { |
michael@0 | 73 | // Don't trigger the "id" getter when the frame is supposed to be freed already |
michael@0 | 74 | if (prop == "id") |
michael@0 | 75 | continue; |
michael@0 | 76 | let propType = typeof(aSandbox[prop]); |
michael@0 | 77 | if (propType == "boolean" || propType == "function" || propType == "number") |
michael@0 | 78 | continue; |
michael@0 | 79 | is(aSandbox[prop], null, "freed " + prop); |
michael@0 | 80 | } |
michael@0 | 81 | run_next_test(); |
michael@0 | 82 | }); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | function reset_server_state() { |
michael@0 | 86 | // Now reset the server state |
michael@0 | 87 | let resetReq = new XMLHttpRequest(); |
michael@0 | 88 | resetReq.open("GET", STATE_URL + "?reset", false); |
michael@0 | 89 | resetReq.send(); |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | function test_creation() { |
michael@0 | 93 | new Sandbox(TEST_URL_1, function sandboxCB(aSandbox) { |
michael@0 | 94 | check_sandbox(aSandbox, TEST_URL_1); |
michael@0 | 95 | free_and_check_sandbox(aSandbox); |
michael@0 | 96 | }); |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | function test_reload() { |
michael@0 | 100 | new Sandbox(TEST_URL_1, function sandboxCB(aSandbox) { |
michael@0 | 101 | check_sandbox(aSandbox, TEST_URL_1); |
michael@0 | 102 | let originalId = aSandbox.id; |
michael@0 | 103 | |
michael@0 | 104 | aSandbox.reload(function sandboxReloadCB(aSandbox) { |
michael@0 | 105 | check_sandbox(aSandbox, TEST_URL_1); |
michael@0 | 106 | is(aSandbox.id, originalId, "Sandbox ID should be the same after reload"); |
michael@0 | 107 | free_and_check_sandbox(aSandbox); |
michael@0 | 108 | }); |
michael@0 | 109 | }); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | function test_url_normalization() { |
michael@0 | 113 | new Sandbox(TEST_URL_2, function sandboxCB(aSandbox) { |
michael@0 | 114 | // TEST_URL_2 should be normalized into the form of TEST_URL_1 |
michael@0 | 115 | check_sandbox(aSandbox, TEST_URL_1); |
michael@0 | 116 | free_and_check_sandbox(aSandbox); |
michael@0 | 117 | }); |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | /** |
michael@0 | 121 | * Check with the server's state to see what content was loaded then reset it. |
michael@0 | 122 | */ |
michael@0 | 123 | function check_loaded_content(aSandbox, aNothingShouldLoad, aCallback) { |
michael@0 | 124 | |
michael@0 | 125 | let xhr = new XMLHttpRequest(); |
michael@0 | 126 | xhr.open("GET", STATE_URL + "?get_loaded", true); |
michael@0 | 127 | xhr.onload = function() { |
michael@0 | 128 | let res = xhr.responseText; |
michael@0 | 129 | is(xhr.status, 200, "Check successful response"); |
michael@0 | 130 | |
michael@0 | 131 | if (aNothingShouldLoad) { |
michael@0 | 132 | is(res, "NOTHING", "Check that nothing was loaded on the server"); |
michael@0 | 133 | } else { |
michael@0 | 134 | let allowedTypes = [ "application/javascript", "text/html", "application/x-test" ]; |
michael@0 | 135 | let loadedTypes = res == "NOTHING" ? [] : res.split(","); |
michael@0 | 136 | |
michael@0 | 137 | for (let loadedType of loadedTypes) { |
michael@0 | 138 | isnot(allowedTypes.indexOf(loadedType), -1, "Check that " + loadedType + " was expected to load"); // TODO |
michael@0 | 139 | } |
michael@0 | 140 | |
michael@0 | 141 | isnot(loadedTypes.indexOf("application/javascript"), -1, "Check JS was loaded"); |
michael@0 | 142 | isnot(loadedTypes.indexOf("text/html"), -1, "Check iframe was loaded"); |
michael@0 | 143 | is(loadedTypes.indexOf("video/webm"), -1, "Check webm was not loaded"); |
michael@0 | 144 | is(loadedTypes.indexOf("audio/ogg"), -1, "Check ogg was not loaded"); |
michael@0 | 145 | |
michael@0 | 146 | // Check that no plugin tags have a type other than TYPE_NULL (failed load) |
michael@0 | 147 | // -- |
michael@0 | 148 | // Checking if a channel was opened is not sufficient for plugin tags -- |
michael@0 | 149 | // An object tag may still be allowed to load a sub-document, but not a |
michael@0 | 150 | // plugin, so it will open a channel but then abort when it gets a |
michael@0 | 151 | // plugin-type. |
michael@0 | 152 | let doc = aSandbox._frame.contentDocument; |
michael@0 | 153 | let nullType = Components.interfaces.nsIObjectLoadingContent.TYPE_NULL; |
michael@0 | 154 | for (let tag of doc.querySelectorAll("embed, object, applet")) { |
michael@0 | 155 | tag instanceof Components.interfaces.nsIObjectLoadingContent; |
michael@0 | 156 | is(tag.displayedType, nullType, "Check that plugin did not load content"); |
michael@0 | 157 | } |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | reset_server_state(); |
michael@0 | 161 | |
michael@0 | 162 | aCallback(); |
michael@0 | 163 | }; |
michael@0 | 164 | xhr.send(); |
michael@0 | 165 | } |
michael@0 | 166 | |
michael@0 | 167 | /** |
michael@0 | 168 | * Helper to check that only certain content is loaded on creation and during reload. |
michael@0 | 169 | */ |
michael@0 | 170 | function check_disabled_content(aSandboxURL, aNothingShouldLoad = false) { |
michael@0 | 171 | new Sandbox(aSandboxURL, function sandboxCB(aSandbox) { |
michael@0 | 172 | check_sandbox(aSandbox, aSandboxURL); |
michael@0 | 173 | let originalId = aSandbox.id; |
michael@0 | 174 | |
michael@0 | 175 | setTimeout(function() { |
michael@0 | 176 | check_loaded_content(aSandbox, aNothingShouldLoad, function checkFinished() { |
michael@0 | 177 | |
michael@0 | 178 | info("reload the sandbox content"); |
michael@0 | 179 | aSandbox.reload(function sandboxReloadCB(aSandbox) { |
michael@0 | 180 | check_sandbox(aSandbox, aSandboxURL); |
michael@0 | 181 | is(aSandbox.id, originalId, "Sandbox ID should be the same after reload"); |
michael@0 | 182 | |
michael@0 | 183 | setTimeout(function() { |
michael@0 | 184 | check_loaded_content(aSandbox, aNothingShouldLoad, function reloadCheckFinished() { |
michael@0 | 185 | free_and_check_sandbox(aSandbox); |
michael@0 | 186 | }); |
michael@0 | 187 | }, 5000); |
michael@0 | 188 | }); |
michael@0 | 189 | }); |
michael@0 | 190 | }, 5000); |
michael@0 | 191 | }); |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | function test_disabled_content() { |
michael@0 | 195 | let url = TEST_BASE + "sandbox_content.html"; |
michael@0 | 196 | check_disabled_content(url); |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | // Same as test above but with content in an iframe. |
michael@0 | 200 | function test_disabled_content_framed() { |
michael@0 | 201 | let url = TEST_BASE + "sandbox_content_framed.html"; |
michael@0 | 202 | check_disabled_content(url); |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | function test_redirect() { |
michael@0 | 206 | let url = TEST_BASE + "sandbox_content_redirect.html"; |
michael@0 | 207 | check_disabled_content(url); |
michael@0 | 208 | } |
michael@0 | 209 | |
michael@0 | 210 | function WindowObserver(aCallback) { |
michael@0 | 211 | this.observe = function(aSubject, aTopic, aData) { |
michael@0 | 212 | if (aTopic != "domwindowopened") { |
michael@0 | 213 | return; |
michael@0 | 214 | } |
michael@0 | 215 | Services.ww.unregisterNotification(this); |
michael@0 | 216 | |
michael@0 | 217 | let domWin = aSubject.QueryInterface(Ci.nsIDOMWindow); |
michael@0 | 218 | ok(!domWin, "No window should be opened"); |
michael@0 | 219 | SimpleTest.executeSoon(function() { |
michael@0 | 220 | info("Closing opened window"); |
michael@0 | 221 | domWin.close(); |
michael@0 | 222 | aCallback(); |
michael@0 | 223 | }); |
michael@0 | 224 | } |
michael@0 | 225 | } |
michael@0 | 226 | |
michael@0 | 227 | // Can the sandbox call window.alert() or popup other UI? |
michael@0 | 228 | function test_alert() { |
michael@0 | 229 | let alertURL = TEST_BASE + "sandbox_content_alert.html"; |
michael@0 | 230 | |
michael@0 | 231 | new Sandbox(alertURL, function sandboxCB(aSandbox) { |
michael@0 | 232 | check_sandbox(aSandbox, alertURL); |
michael@0 | 233 | setTimeout(function() { |
michael@0 | 234 | |
michael@0 | 235 | let win = Services.wm.getMostRecentWindow(null); |
michael@0 | 236 | isnot(win.document.documentElement.getAttribute("id"), "commonDialog", |
michael@0 | 237 | "Make sure most recent window is not a dialog"); |
michael@0 | 238 | if (win.document.documentElement.getAttribute("id") == "commonDialog") { |
michael@0 | 239 | // If a dialog did open, close it so we don't interfere with future tests |
michael@0 | 240 | win.close() |
michael@0 | 241 | } |
michael@0 | 242 | |
michael@0 | 243 | free_and_check_sandbox(aSandbox); |
michael@0 | 244 | }, 1000); |
michael@0 | 245 | }); |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | // Can the sandboxed page open a popup with window.open? |
michael@0 | 249 | function test_popup() { |
michael@0 | 250 | let alertURL = TEST_BASE + "sandbox_content_popup.html"; |
michael@0 | 251 | let theSandbox; |
michael@0 | 252 | function continueTest() { |
michael@0 | 253 | // avoid double-free |
michael@0 | 254 | if (!theSandbox) |
michael@0 | 255 | return; |
michael@0 | 256 | free_and_check_sandbox(theSandbox); |
michael@0 | 257 | theSandbox = null; |
michael@0 | 258 | } |
michael@0 | 259 | let winObs = new WindowObserver(continueTest); |
michael@0 | 260 | Services.ww.registerNotification(winObs); |
michael@0 | 261 | new Sandbox(alertURL, function sandboxCB(aSandbox) { |
michael@0 | 262 | theSandbox = aSandbox; |
michael@0 | 263 | check_sandbox(aSandbox, alertURL); |
michael@0 | 264 | // Wait 5 seconds to see if the window is going to open. |
michael@0 | 265 | setTimeout(function() { |
michael@0 | 266 | Services.ww.unregisterNotification(winObs); |
michael@0 | 267 | continueTest(); |
michael@0 | 268 | }, 5000); |
michael@0 | 269 | }); |
michael@0 | 270 | } |
michael@0 | 271 | |
michael@0 | 272 | // Loading a page with a bad cert |
michael@0 | 273 | function test_bad_cert() { |
michael@0 | 274 | let url = TEST_BASE + "sandbox_content.sjs?text/html"; |
michael@0 | 275 | url = url.replace("http://mochi.test:8888", "https://untrusted.example.com"); |
michael@0 | 276 | check_disabled_content(url, /*nothingShouldLoad=*/true); |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | // Loading a page to check window.top and other permissions. |
michael@0 | 280 | function test_frame_perms() { |
michael@0 | 281 | let url = TEST_BASE + "sandbox_content_perms.html"; |
michael@0 | 282 | new Sandbox(url, function sandboxCB(aSandbox) { |
michael@0 | 283 | check_sandbox(aSandbox, url); |
michael@0 | 284 | |
michael@0 | 285 | // Give the content time to load |
michael@0 | 286 | setTimeout(function() { |
michael@0 | 287 | let xhr = new XMLHttpRequest(); |
michael@0 | 288 | xhr.open("GET", STATE_URL + "?get_loaded", true); |
michael@0 | 289 | xhr.responseType = "json"; |
michael@0 | 290 | xhr.onload = function() { |
michael@0 | 291 | is(xhr.status, 200, "Check successful response"); |
michael@0 | 292 | is(typeof(xhr.response), "object", "Check response is object"); |
michael@0 | 293 | is(Object.keys(xhr.response).length, 3, "Check the number of perm. tests"); |
michael@0 | 294 | for (let test in xhr.response) { |
michael@0 | 295 | ok(xhr.response[test], "Check result of " + test); |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | reset_server_state(); |
michael@0 | 299 | free_and_check_sandbox(aSandbox); |
michael@0 | 300 | }; |
michael@0 | 301 | xhr.send(); |
michael@0 | 302 | }, 3000); |
michael@0 | 303 | }); |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | let TESTS = [test_creation, test_reload, test_url_normalization]; |
michael@0 | 307 | TESTS.push(test_disabled_content, test_disabled_content_framed); |
michael@0 | 308 | TESTS.push(test_alert, test_popup, test_bad_cert); |
michael@0 | 309 | TESTS.push(test_redirect, test_frame_perms); |
michael@0 | 310 | |
michael@0 | 311 | function run_next_test() { |
michael@0 | 312 | if (TESTS.length) { |
michael@0 | 313 | let test = TESTS.shift(); |
michael@0 | 314 | info(test.name); |
michael@0 | 315 | test(); |
michael@0 | 316 | } else { |
michael@0 | 317 | Services.prefs.clearUserPref("toolkit.identity.debug"); |
michael@0 | 318 | SimpleTest.finish(); |
michael@0 | 319 | } |
michael@0 | 320 | } |
michael@0 | 321 | |
michael@0 | 322 | ]]> |
michael@0 | 323 | </script> |
michael@0 | 324 | </window> |