tor-browser

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

test_blockParsing.js (3358B)


      1 "use strict";
      2 
      3 const { TestUtils } = ChromeUtils.importESModule(
      4  "resource://testing-common/TestUtils.sys.mjs"
      5 );
      6 const { XPCShellContentUtils } = ChromeUtils.importESModule(
      7  "resource://testing-common/XPCShellContentUtils.sys.mjs"
      8 );
      9 const { setTimeout } = ChromeUtils.importESModule(
     10  "resource://gre/modules/Timer.sys.mjs"
     11 );
     12 
     13 XPCShellContentUtils.init(this);
     14 
     15 function delay() {
     16  return new Promise(resolve => {
     17    setTimeout(resolve, 0);
     18  });
     19 }
     20 
     21 const server = XPCShellContentUtils.createHttpServer({
     22  hosts: ["example.com"],
     23 });
     24 
     25 // XML document with only a <script> tag as the document element.
     26 const PAGE_URL = "http://example.com/";
     27 server.registerPathHandler("/", (request, response) => {
     28  response.setHeader("Content-Type", "application/xhtml+xml");
     29  response.write(String.raw`<!DOCTYPE html>
     30    <script xmlns="http://www.w3.org/1999/xhtml" src="slow.js"/>
     31  `);
     32 });
     33 
     34 let resolveResumeScriptPromise;
     35 let resumeScriptPromise = new Promise(resolve => {
     36  resolveResumeScriptPromise = resolve;
     37 });
     38 
     39 let resolveScriptRequestPromise;
     40 let scriptRequestPromise = new Promise(resolve => {
     41  resolveScriptRequestPromise = resolve;
     42 });
     43 
     44 // An empty script which waits to complete until `resumeScriptPromise`
     45 // resolves.
     46 server.registerPathHandler("/slow.js", async (request, response) => {
     47  response.processAsync();
     48  resolveScriptRequestPromise();
     49 
     50  await resumeScriptPromise;
     51 
     52  response.setHeader("Content-type", "text/javascript");
     53  response.write("");
     54  response.finish();
     55 });
     56 
     57 add_setup(function () {
     58  Services.prefs.setBoolPref("security.allow_unsafe_parent_loads", true);
     59 });
     60 
     61 registerCleanupFunction(function () {
     62  Services.prefs.clearUserPref("security.allow_unsafe_parent_loads");
     63 });
     64 
     65 // Tests that attempting to block parsing for a <script> tag while the
     66 // parser is already blocked is handled correctly, and does not cause
     67 // crashes or hangs.
     68 add_task(async function test_nested_blockParser() {
     69  // Wait for the document element of the page to be inserted, and block
     70  // the parser when it is.
     71  let resolveBlockerPromise;
     72  let blockerPromise;
     73  let docElementPromise = TestUtils.topicObserved(
     74    "document-element-inserted",
     75    doc => {
     76      if (doc.location.href === PAGE_URL) {
     77        blockerPromise = new Promise(resolve => {
     78          resolveBlockerPromise = resolve;
     79        });
     80 
     81        doc.blockParsing(blockerPromise);
     82        return true;
     83      }
     84      return false;
     85    }
     86  );
     87 
     88  // Begin loading the page.
     89  let pagePromise = XPCShellContentUtils.loadContentPage(PAGE_URL, {
     90    remote: false,
     91  });
     92 
     93  // Wait for the document element to be inserted.
     94  await docElementPromise;
     95  // Wait for the /slow.js script request to initiate.
     96  await scriptRequestPromise;
     97 
     98  // Make some trips through the event loop to be safe.
     99  await delay();
    100  await delay();
    101 
    102  // Allow the /slow.js script request to complete.
    103  resolveResumeScriptPromise();
    104 
    105  // Make some trips through the event loop so that the <script> request
    106  // unblocks the parser.
    107  await delay();
    108  await delay();
    109 
    110  // Release the parser blocker added in the observer above.
    111  resolveBlockerPromise();
    112 
    113  // Make some trips through the event loop to allow the parser to
    114  // unblock.
    115  await delay();
    116  await delay();
    117 
    118  // Wait for the document to finish loading, and then close it.
    119  let page = await pagePromise;
    120  await page.close();
    121 });