tor-browser

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

window-open-noopener.html (5085B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>window.open() with "noopener" tests</title>
      4 
      5 <meta name="variant" content="?indexed">
      6 <meta name="variant" content="?_self">
      7 <meta name="variant" content="?_parent">
      8 <meta name="variant" content="?_top">
      9 <meta name=timeout content=long>
     10 
     11 <script src=/resources/testharness.js></script>
     12 <script src=/resources/testharnessreport.js></script>
     13 <script>
     14 var testData = [
     15  { testDescription: "window.open() with 'noopener' should reuse existing target",
     16    secondWindowFeatureString: "noopener",
     17    shouldReturnWindow: false },
     18  { testDescription: "noopener=1 means the same as noopener",
     19    secondWindowFeatureString: "noopener=1",
     20    shouldReturnWindow: false },
     21  { testDescription: "noopener=true means the same as noopener",
     22    secondWindowFeatureString: "noopener=true",
     23    shouldReturnWindow: false },
     24  { testDescription: "noopener=0 means lack of noopener",
     25    secondWindowFeatureString: "noopener=0",
     26    shouldReturnWindow: true },
     27  { testDescription: "noopener separated only by spaces should work",
     28    secondWindowFeatureString: "make me noopener",
     29    shouldReturnWindow: false },
     30  { testDescription: "Trailing noopener should work",
     31    secondWindowFeatureString: "abc def,  \n\r noopener",
     32    shouldReturnWindow: false },
     33  { testDescription: "Leading noopener should work",
     34    secondWindowFeatureString: "noopener \f\t , hey, there",
     35    shouldReturnWindow: false },
     36  { testDescription: "Interior noopener should work",
     37    secondWindowFeatureString: "and now, noopener   , hey, there",
     38    shouldReturnWindow: false },
     39  { testDescription: "noreferrer should also suppress opener when reusing existing target",
     40    secondWindowFeatureString: "noreferrer",
     41    shouldReturnWindow: false },
     42 ];
     43 
     44 /**
     45 * Loop over our testData array and kick off an async test for each entry.  Each
     46 * async test opens a window using window.open() with some per-test unique name,
     47 * then tries to do a second window.open() call with the same name and the
     48 * test-specific feature string.  It then checks whether that second
     49 * window.open() call reuses the existing window, whether the return value of
     50 * the second window.open() call is correct (it should be null in the noopener
     51 * cases and non-null in the cases when the existing window gets reused) and so
     52 * forth.
     53 */
     54 function indexedTests() {
     55  var tests = [];
     56  for(var i = 0; i < testData.length; ++i) {
     57    var test = testData[i];
     58    var t = async_test(test.testDescription);
     59    tests.push(t);
     60    t.secondWindowFeatureString = test.secondWindowFeatureString;
     61    t.windowName = "someuniquename" + i;
     62 
     63    if (test.shouldReturnWindow) {
     64      t.step(function() {
     65        var windowName = this.windowName;
     66 
     67        var w1 = window.open("", windowName);
     68        this.add_cleanup(function() { w1.close(); });
     69 
     70        assert_equals(w1.opener, window);
     71 
     72        var w2 = window.open("", windowName, this.secondWindowFeatureString);
     73        assert_equals(w2, w1);
     74        assert_equals(w2.opener, w1.opener);
     75        assert_equals(w2.opener, window);
     76        this.done();
     77      });
     78    } else {
     79      t.step(function() {
     80        var w1;
     81        this.add_cleanup(function() {
     82          w1.close();
     83          channel.postMessage(null);
     84        });
     85 
     86        var windowName = this.windowName;
     87        var channel = new BroadcastChannel(windowName);
     88 
     89        channel.onmessage = this.step_func_done(function(e) {
     90          var data = e.data;
     91          assert_equals(data.name, windowName, "Should have the right name");
     92          assert_equals(data.haveOpener, true, "Should still have opener");
     93          assert_equals(w1.opener, window);
     94          assert_not_equals(w1.location.href, "about:blank", "Should have navigated");
     95        });
     96 
     97        w1 = window.open("", windowName);
     98        assert_equals(w1.opener, window);
     99 
    100        var w2 = window.open("support/noopener-target.html?" + windowName,
    101                            windowName, this.secondWindowFeatureString);
    102        assert_equals(w2, null);
    103 
    104        assert_equals(w1.opener, window);
    105      });
    106    }
    107  }
    108 }
    109 
    110 /**
    111 * Loop over the special targets that ignore noopener and check that doing a
    112 * window.open() with those targets correctly reuses the existing window.
    113 */
    114 function specialTargetTest(target) {
    115  if (["_self", "_parent", "_top"].includes(target)) {
    116    var t = async_test("noopener window.open targeting " + target);
    117    t.openedWindow = window.open(`javascript:var w2 = window.open("", "${target}", "noopener"); this.checkValues(w2); this.close(); void(0);`);
    118    assert_equals(t.openedWindow.opener, window);
    119    t.openedWindow.checkValues = t.step_func_done(function(win) {
    120      assert_equals(win, this.openedWindow);
    121    });
    122  } else {
    123    throw 'testError: special target must be one of: _self, _parent, _top'
    124  }
    125 }
    126 
    127 /**
    128 * Parse the Query string, check if it matches keyword 'indexed' to run the indexed tests,
    129 * otherwise test it as a special target
    130 */
    131 var variant = window.location.href.split("?")[1]
    132 if(variant == "indexed") {
    133  indexedTests();
    134 } else {
    135  specialTargetTest(variant);
    136 }
    137 </script>