tor-browser

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

browser_net_save_response_as_sanitization.js (4275B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 var MockFilePicker = SpecialPowers.MockFilePicker;
      7 MockFilePicker.init(window.browsingContext);
      8 
      9 /**
     10 * Tests that filenames are sanitized when using Save Response As
     11 */
     12 
     13 function setupTestServer() {
     14  const httpServer = createTestHTTPServer();
     15  httpServer.registerContentType("html", "text/html");
     16 
     17  httpServer.registerPathHandler("/index.html", function (request, response) {
     18    response.setStatusLine(request.httpVersion, 200, "OK");
     19    response.write(`<!DOCTYPE html>
     20    <html><body><h1>Test sanitization for save response as
     21    <script>fetch("test.url");</script>
     22    <script>fetch("test2.url");</script>
     23    `);
     24  });
     25 
     26  httpServer.registerPathHandler("/test.url", function (request, response) {
     27    response.setStatusLine(request.httpVersion, 200, "OK");
     28    response.setHeader("Content-Type", "text/plain", false);
     29    response.write("dummy content");
     30  });
     31  httpServer.registerPathHandler("/test2.url", function (request, response) {
     32    response.setStatusLine(request.httpVersion, 200, "OK");
     33    response.setHeader("Content-Type", "text/plain", false);
     34    response.write("dummy content 2");
     35  });
     36 
     37  return httpServer;
     38 }
     39 
     40 add_task(async function () {
     41  const httpServer = setupTestServer();
     42  const port = httpServer.identity.primaryPort;
     43 
     44  const { monitor } = await initNetMonitor(
     45    `http://localhost:${port}/index.html`,
     46    {
     47      requestCount: 3,
     48    }
     49  );
     50 
     51  info("Starting test... ");
     52  const { document } = monitor.panelWin;
     53 
     54  info("Reload the browser to show the 2 requests for the page");
     55  const networkEvent = waitForNetworkEvents(monitor, 3);
     56  await reloadBrowser();
     57  await networkEvent;
     58 
     59  // Create the folder the gzip file will be saved into
     60  const destDir = createTemporarySaveDirectory();
     61  let destFile;
     62 
     63  // Prepare the MockFilePicker
     64  MockFilePicker.displayDirectory = destDir;
     65  registerCleanupFunction(function () {
     66    MockFilePicker.cleanup();
     67  });
     68 
     69  info("Prepare a file picker mock which will use the default filename");
     70  let saveDialogClosedPromise = new Promise(resolve => {
     71    MockFilePicker.showCallback = function (fp) {
     72      info("MockFilePicker showCallback - preserve .download extension");
     73      const fileName = fp.defaultString;
     74      destFile = destDir.clone();
     75      destFile.append(fileName);
     76      MockFilePicker.setFiles([destFile]);
     77 
     78      resolve(destFile.path);
     79    };
     80  });
     81 
     82  info("Save response as for the test.url request");
     83  await triggerSaveResponseAs(
     84    monitor,
     85    document.querySelectorAll(".request-list-item")[1]
     86  );
     87 
     88  info("Wait for the save dialog to close");
     89  const filePickerPath = await saveDialogClosedPromise;
     90 
     91  const expectedFile = destDir.clone();
     92  expectedFile.append("test.url.download");
     93  is(
     94    filePickerPath,
     95    expectedFile.path,
     96    "File picker default filename was set to the expected value"
     97  );
     98 
     99  await waitForFileSavedToDisk(expectedFile.path);
    100 
    101  info("Prepare a file picker mock which will override the default filename");
    102  saveDialogClosedPromise = new Promise(resolve => {
    103    MockFilePicker.showCallback = function (fp) {
    104      info("MockFilePicker showCallback - strip .download extension");
    105      const fileName = fp.defaultString;
    106      destFile = destDir.clone();
    107      destFile.append(fileName.replace(".download", ""));
    108      MockFilePicker.setFiles([destFile]);
    109 
    110      resolve(destFile.path);
    111    };
    112  });
    113 
    114  info("Save response as for test2.url");
    115  await triggerSaveResponseAs(
    116    monitor,
    117    document.querySelectorAll(".request-list-item")[2]
    118  );
    119 
    120  info("Wait for the save dialog to close");
    121  const updatedFilePickerPath = await saveDialogClosedPromise;
    122 
    123  const invalidFile = destDir.clone();
    124  invalidFile.append("test2.url");
    125 
    126  const expectedFile2 = destDir.clone();
    127  expectedFile2.append("test2.url.download");
    128 
    129  is(
    130    updatedFilePickerPath,
    131    invalidFile.path,
    132    "File picker filename was updated to an invalid path while saving"
    133  );
    134 
    135  // Check that the valid path was still used to save the file.
    136  await waitForFileSavedToDisk(expectedFile2.path);
    137 
    138  ok(
    139    !(await IOUtils.exists(invalidFile.path)),
    140    "No file was saved for the invalid path"
    141  );
    142 
    143  await teardown(monitor);
    144 });