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 });