tor-browser

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

test_bug732665.xhtml (4053B)


      1 <?xml version="1.0"?>
      2 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
      3 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
      4 <!--
      5 https://bugzilla.mozilla.org/show_bug.cgi?id=732665
      6 -->
      7 <window title="Mozilla Bug 732665"
      8        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      9  <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
     10 
     11  <!-- test results are displayed in the html:body -->
     12  <body xmlns="http://www.w3.org/1999/xhtml">
     13  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=732665"
     14     target="_blank">Mozilla Bug 732665</a>
     15  </body>
     16 
     17  <!-- test code goes here -->
     18  <script type="application/javascript">
     19  <![CDATA[
     20 
     21 add_task(async () => {
     22  await SpecialPowers.pushPrefEnv({"set": [["security.allow_eval_with_system_principal",
     23                                            true]]});
     24  //
     25  // Important! If this test starts failing after a tricky platform-y change,
     26  // the stack quota numbers in XPCJSContext probably need twiddling. We want
     27  // to maintain the invariants in this test (at least to some approximation)
     28  // for security reasons.
     29  //
     30 
     31  // Executes f() d steps from the probed native stack limit, and returns
     32  // the number of steps to the recursion limit from the caller.
     33  function nearNativeStackLimit(d, f) {
     34    f = f || function() {};
     35    let failed = null;
     36    function inner() {
     37      try {
     38        // eslint-disable-next-line no-eval
     39        var stepsFromLimit = eval("inner()"); // Use eval to force a number of native stackframes to be created.
     40        if (stepsFromLimit == d) {
     41          try {
     42            f();
     43          } catch(e) {
     44            // If we didn't have enough stack space to call the (possibly
     45            // trivial) test function above, we obviously can't expect to call
     46            // into the test harness assertion code successfully.
     47            failed = e;
     48          }
     49        }
     50        return stepsFromLimit + 1;
     51      } catch(e) {
     52      // It would be nice to check here that the exception is actually an
     53      // over-recursion here. But doing so would require toString()ing the
     54      // exception, which we may not have the stack space to do.
     55        return 0;
     56      }
     57    }
     58    let result = inner();
     59    ok(!failed, `nearNativeStackLimit callback threw: ${failed}`);
     60    return result;
     61  }
     62 
     63  var contentSb = new Cu.Sandbox("https://www.example.com");
     64  var chromeSb = new Cu.Sandbox(window);
     65  chromeSb.ok = contentSb.ok = ok;
     66  Cu.evalInSandbox(nearNativeStackLimit.toSource(), chromeSb);
     67  Cu.evalInSandbox(nearNativeStackLimit.toSource(), contentSb);
     68  var chromeLimit = Cu.evalInSandbox("nearNativeStackLimit(0);", chromeSb);
     69  var contentLimit = Cu.evalInSandbox("nearNativeStackLimit(0)", contentSb);
     70  ok(chromeLimit >= contentLimit + 10,
     71     "Chrome should be able to have at least 10 heavy frames more stack than content: " + chromeLimit + ", " + contentLimit);
     72 
     73  // Exhaust the stack space in content, and then make sure we can still get 10
     74  // heavy frames in chrome.
     75  //
     76  // Note that sometimes, if we pass |0| to nearNativeStackLimit, we can end up
     77  // so close to the border in content that we can't even get ourselves together
     78  // enough to make the cross-compartment call. So rather than exhausting the
     79  // stack entirely and then checking for 10 chrome frames, we leave ourselves
     80  // one frame's worth, and check for 11.
     81  //
     82  // If this assertion fails, the current work-around so far is to measure
     83  // again the worst frame size, by using the JS Shell to run
     84  // test_bug732665_meta.js . This script will output numbers to update
     85  // XPCJSContext.cpp comment, as well as the kTrustedScriptBuffer constant.
     86  contentSb.nnslChrome = chromeSb.nearNativeStackLimit;
     87  var nestedLimit = Cu.evalInSandbox("nearNativeStackLimit(1, function() { nestedLimit = nnslChrome(0);}); nestedLimit;", contentSb);
     88  ok(nestedLimit >= 11, "Chrome should be invokable from content script with an exhausted stack: " + nestedLimit);
     89 });
     90  ]]>
     91  </script>
     92 </window>