tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

head.js (10018B)


      1 const REFERRER_URL_BASE = "/browser/browser/base/content/test/referrer/";
      2 const REFERRER_POLICYSERVER_URL =
      3  "test1.example.com" + REFERRER_URL_BASE + "file_referrer_policyserver.sjs";
      4 const REFERRER_POLICYSERVER_URL_ATTRIBUTE =
      5  "test1.example.com" +
      6  REFERRER_URL_BASE +
      7  "file_referrer_policyserver_attr.sjs";
      8 
      9 var gTestWindow = null;
     10 var rounds = 0;
     11 
     12 // We test that the UI code propagates three pieces of state - the referrer URI
     13 // itself, the referrer policy, and the triggering principal. After that, we
     14 // trust nsIWebNavigation to do the right thing with the info it's given, which
     15 // is covered more exhaustively by dom/base/test/test_bug704320.html (which is
     16 // a faster content-only test). So, here, we limit ourselves to cases that
     17 // would break when the UI code drops either of these pieces; we don't try to
     18 // duplicate the entire cross-product test in bug 704320 - that would be slow,
     19 // especially when we're opening a new window for each case.
     20 var _referrerTests = [
     21  // 1. Normal cases - no referrer policy, no special attributes.
     22  //    We expect a full referrer normally, and no referrer on downgrade.
     23  {
     24    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     25    fromScheme: "http://",
     26    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     27    toScheme: "http://",
     28    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     29    result: "http://test1.example.com/browser", // full referrer
     30  },
     31  {
     32    fromScheme: "https://",
     33    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     34    toScheme: "http://",
     35    result: "", // no referrer when downgrade
     36  },
     37  // 2. Origin referrer policy - we expect an origin referrer,
     38  //    even on downgrade.  But rel=noreferrer trumps this.
     39  {
     40    fromScheme: "https://",
     41    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     42    toScheme: "http://",
     43    policy: "origin",
     44    result: "https://test1.example.com/", // origin, even on downgrade
     45  },
     46  {
     47    fromScheme: "https://",
     48    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     49    toScheme: "http://",
     50    policy: "origin",
     51    rel: "noreferrer",
     52    result: "", // rel=noreferrer trumps meta-referrer
     53  },
     54  // 3. XXX: using no-referrer here until we support all attribute values (bug 1178337)
     55  //    Origin-when-cross-origin policy - this depends on the triggering
     56  //    principal.  We expect full referrer for same-origin requests,
     57  //    and origin referrer for cross-origin requests.
     58  {
     59    fromScheme: "https://",
     60    toScheme: "https://",
     61    policy: "no-referrer",
     62    result: "", // same origin https://test1.example.com/browser
     63  },
     64  {
     65    // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     66    fromScheme: "http://",
     67    toScheme: "https://",
     68    policy: "no-referrer",
     69    result: "", // cross origin http://test1.example.com
     70  },
     71 ];
     72 
     73 /**
     74 * Returns the test object for a given test number.
     75 *
     76 * @param aTestNumber The test number - 0, 1, 2, ...
     77 * @return The test object, or undefined if the number is out of range.
     78 */
     79 function getReferrerTest(aTestNumber) {
     80  return _referrerTests[aTestNumber];
     81 }
     82 
     83 /**
     84 * Returns shimmed test object for a given test number.
     85 *
     86 * @param aTestNumber The test number - 0, 1, 2, ...
     87 * @return The test object with result hard-coded to "",
     88 *          or undefined if the number is out of range.
     89 */
     90 function getRemovedReferrerTest(aTestNumber) {
     91  let testCase = _referrerTests[aTestNumber];
     92  if (testCase) {
     93    // We want all the referrer tests to fail!
     94    testCase.result = "";
     95  }
     96 
     97  return testCase;
     98 }
     99 
    100 /**
    101 * Returns a brief summary of the test, for logging.
    102 *
    103 * @param aTestNumber The test number - 0, 1, 2...
    104 * @return The test description.
    105 */
    106 function getReferrerTestDescription(aTestNumber) {
    107  let test = getReferrerTest(aTestNumber);
    108  return (
    109    "policy=[" +
    110    test.policy +
    111    "] " +
    112    "rel=[" +
    113    test.rel +
    114    "] " +
    115    test.fromScheme +
    116    " -> " +
    117    test.toScheme
    118  );
    119 }
    120 
    121 /**
    122 * Clicks the link.
    123 *
    124 * @param aWindow The window to click the link in.
    125 * @param aLinkId The id of the link element.
    126 * @param aOptions The options for synthesizeMouseAtCenter.
    127 */
    128 function clickTheLink(aWindow, aLinkId, aOptions) {
    129  return BrowserTestUtils.synthesizeMouseAtCenter(
    130    "#" + aLinkId,
    131    aOptions,
    132    aWindow.gBrowser.selectedBrowser
    133  );
    134 }
    135 
    136 /**
    137 * Extracts the referrer result from the target window.
    138 *
    139 * @param aWindow The window where the referrer target has loaded.
    140 * @returns {Promise<string>}
    141 *   Resolves to the text of the (trimmed) referrer when extracted.
    142 */
    143 function referrerResultExtracted(aWindow) {
    144  return SpecialPowers.spawn(aWindow.gBrowser.selectedBrowser, [], function () {
    145    return content.document.getElementById("testdiv").textContent;
    146  });
    147 }
    148 
    149 /**
    150 * Waits for browser delayed startup to finish.
    151 *
    152 * @param aWindow The window to wait for.
    153 * @returns {Promise<void>}
    154 *   Resolves when the window is loaded.
    155 */
    156 function delayedStartupFinished(aWindow) {
    157  return new Promise(function (resolve) {
    158    Services.obs.addObserver(function observer(aSubject, aTopic) {
    159      if (aWindow == aSubject) {
    160        Services.obs.removeObserver(observer, aTopic);
    161        resolve();
    162      }
    163    }, "browser-delayed-startup-finished");
    164  });
    165 }
    166 
    167 /**
    168 * Waits for some (any) tab to load. The caller triggers the load.
    169 *
    170 * @param aWindow The window where to wait for a tab to load.
    171 * @returns {Promise}
    172 *   Resolves to the tab once it's loaded.
    173 */
    174 function someTabLoaded() {
    175  return BrowserTestUtils.waitForNewTab(gTestWindow.gBrowser, null, true);
    176 }
    177 
    178 /**
    179 * Waits for a new window to open and load. The caller triggers the open.
    180 *
    181 * @returns {Promise<Window>}
    182 *   Resolves to the new window once it's open and loaded.
    183 */
    184 function newWindowOpened() {
    185  return TestUtils.topicObserved("browser-delayed-startup-finished").then(
    186    ([win]) => win
    187  );
    188 }
    189 
    190 /**
    191 * Opens the context menu.
    192 *
    193 * @param aWindow The window to open the context menu in.
    194 * @param aLinkId The id of the link to open the context menu on.
    195 * @returns {Promise}
    196 *   Resolves with the menu popup when the context menu is open.
    197 */
    198 function contextMenuOpened(aWindow, aLinkId) {
    199  let popupShownPromise = BrowserTestUtils.waitForEvent(
    200    aWindow.document,
    201    "popupshown"
    202  );
    203  // Simulate right-click.
    204  clickTheLink(aWindow, aLinkId, { type: "contextmenu", button: 2 });
    205  return popupShownPromise.then(e => e.target);
    206 }
    207 
    208 /**
    209 * Performs a context menu command.
    210 *
    211 * @param aWindow The window with the already open context menu.
    212 * @param aMenu The menu popup to hide.
    213 * @param aItemId The id of the menu item to activate.
    214 */
    215 function doContextMenuCommand(aWindow, aMenu, aItemId) {
    216  let command = aWindow.document.getElementById(aItemId);
    217  command.doCommand();
    218  aMenu.hidePopup();
    219 }
    220 
    221 /**
    222 * Loads a single test case, i.e., a source url into gTestWindow.
    223 *
    224 * @param aTestNumber The test case number - 0, 1, 2...
    225 * @returns {Promise<void>}
    226 *   Resolves when the source url for this test case is loaded.
    227 */
    228 function referrerTestCaseLoaded(aTestNumber, aParams) {
    229  let test = getReferrerTest(aTestNumber);
    230  let server =
    231    rounds == 0
    232      ? REFERRER_POLICYSERVER_URL
    233      : REFERRER_POLICYSERVER_URL_ATTRIBUTE;
    234  let url =
    235    test.fromScheme +
    236    server +
    237    "?scheme=" +
    238    escape(test.toScheme) +
    239    "&policy=" +
    240    escape(test.policy || "") +
    241    "&rel=" +
    242    escape(test.rel || "") +
    243    "&cross=" +
    244    escape(test.cross || "");
    245  let browser = gTestWindow.gBrowser;
    246  return BrowserTestUtils.openNewForegroundTab(
    247    browser,
    248    () => {
    249      browser.selectedTab = BrowserTestUtils.addTab(browser, url, aParams);
    250    },
    251    false,
    252    true
    253  );
    254 }
    255 
    256 /**
    257 * Checks the result of the referrer test, and moves on to the next test.
    258 *
    259 * @param aTestNumber The test number - 0, 1, 2, ...
    260 * @param aNewWindow The new window where the referrer target opened, or null.
    261 * @param aNewTab The new tab where the referrer target opened, or null.
    262 * @param aStartTestCase The callback to start the next test, aTestNumber + 1.
    263 */
    264 function checkReferrerAndStartNextTest(
    265  aTestNumber,
    266  aNewWindow,
    267  aNewTab,
    268  aStartTestCase,
    269  aParams = {}
    270 ) {
    271  referrerResultExtracted(aNewWindow || gTestWindow).then(function (result) {
    272    // Compare the actual result against the expected one.
    273    let test = getReferrerTest(aTestNumber);
    274    let desc = getReferrerTestDescription(aTestNumber);
    275    is(result, test.result, desc);
    276 
    277    // Clean up - close new tab / window, and then the source tab.
    278    aNewTab && (aNewWindow || gTestWindow).gBrowser.removeTab(aNewTab);
    279    aNewWindow && aNewWindow.close();
    280    is(gTestWindow.gBrowser.tabs.length, 2, "two tabs open");
    281    gTestWindow.gBrowser.removeTab(gTestWindow.gBrowser.tabs[1]);
    282 
    283    // Move on to the next test.  Or finish if we're done.
    284    var nextTestNumber = aTestNumber + 1;
    285    if (getReferrerTest(nextTestNumber)) {
    286      referrerTestCaseLoaded(nextTestNumber, aParams).then(function () {
    287        aStartTestCase(nextTestNumber);
    288      });
    289    } else if (rounds == 0) {
    290      nextTestNumber = 0;
    291      rounds = 1;
    292      referrerTestCaseLoaded(nextTestNumber, aParams).then(function () {
    293        aStartTestCase(nextTestNumber);
    294      });
    295    } else {
    296      finish();
    297    }
    298  });
    299 }
    300 
    301 /**
    302 * Fires up the complete referrer test.
    303 *
    304 * @param aStartTestCase The callback to start a single test case, called with
    305 * the test number - 0, 1, 2... Needs to trigger the navigation from the source
    306 * page, and call checkReferrerAndStartNextTest() when the target is loaded.
    307 */
    308 function startReferrerTest(aStartTestCase, params = {}) {
    309  waitForExplicitFinish();
    310 
    311  // Open the window where we'll load the source URLs.
    312  gTestWindow = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
    313  registerCleanupFunction(function () {
    314    gTestWindow && gTestWindow.close();
    315  });
    316 
    317  // Load and start the first test.
    318  delayedStartupFinished(gTestWindow).then(function () {
    319    referrerTestCaseLoaded(0, params).then(function () {
    320      aStartTestCase(0);
    321    });
    322  });
    323 }