toolkit/identity/tests/chrome/test_sandbox.xul

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial