tor-browser

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

navigate.window.js (2551B)


      1 // META: timeout=long
      2 //
      3 // Test some edge cases around navigation to data: URLs to ensure they use the same code path
      4 
      5 [
      6  {
      7    input: "data:text/html,<script>parent.postMessage(1, '*')</script>",
      8    result: 1,
      9    name: "Nothing fancy",
     10  },
     11  {
     12    input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoMiwgJyonKTwvc2NyaXB0Pg==",
     13    result: 2,
     14    name: "base64",
     15  },
     16  {
     17    input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNCwgJyonKTwvc2NyaXB0Pr+/",
     18    result: 4,
     19    name: "base64 with code points that differ from base64url"
     20  },
     21  {
     22    input: "data:text/html;base64,PHNjcml%09%20%20%0A%0C%0DwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNiwgJyonKTwvc2NyaXB0Pg==",
     23    result: 6,
     24    name: "ASCII whitespace in the input is removed"
     25  }
     26 ].forEach(({ input, result, name }) => {
     27  // Use promise_test so they go sequentially
     28  promise_test(async t => {
     29    const event = await new Promise((resolve, reject) => {
     30      self.addEventListener("message", t.step_func(resolve), { once: true });
     31      const frame = document.body.appendChild(document.createElement("iframe"));
     32      t.add_cleanup(() => frame.remove());
     33 
     34      // The assumption is that postMessage() is quicker
     35      t.step_timeout(reject, 500);
     36      frame.src = input;
     37    });
     38    assert_equals(event.data, result);
     39  }, name);
     40 });
     41 
     42 // Failure cases
     43 [
     44  {
     45    input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoMywgJyonKTwvc2NyaXB0Pg=",
     46    name: "base64 with incorrect padding",
     47  },
     48  {
     49    input: "data:text/html;base64,PHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNSwgJyonKTwvc2NyaXB0Pr-_",
     50    name: "base64url is not supported"
     51  },
     52  {
     53    input: "data:text/html;base64,%0BPHNjcmlwdD5wYXJlbnQucG9zdE1lc3NhZ2UoNywgJyonKTwvc2NyaXB0Pg==",
     54    name: "Vertical tab in the input leads to an error"
     55  }
     56 ].forEach(({ input, name }) => {
     57  // Continue to use promise_test so they go sequentially
     58  promise_test(async t => {
     59    const event = await new Promise((resolve, reject) => {
     60      self.addEventListener("message", t.step_func(reject), { once: true });
     61      const frame = document.body.appendChild(document.createElement("iframe"));
     62      t.add_cleanup(() => frame.remove());
     63 
     64      // The assumption is that postMessage() is quicker
     65      t.step_timeout(resolve, 500);
     66      frame.src = input;
     67    });
     68  }, name);
     69 });
     70 
     71 // I found some of the interesting code point cases above through brute force:
     72 //
     73 // for (i = 0; i < 256; i++) {
     74 //   w(btoa("<script>parent.postMessage(5, '*')<\/script>" + String.fromCodePoint(i) + String.fromCodePoint(i)));
     75 // }