Bug 1941725 - Test iframe sandboxed PDFs. r=smaug
PDFs in sandboxed iframes are blocked when handled internally, regardless of sandbox flag. If the sandbox flag is `allow-downloads` and the default action is to not show the PDF inline, allow the action. Differential Revision: https://phabricator.services.mozilla.com/D245896
This commit is contained in:
@@ -118,6 +118,9 @@ support-files = [
|
||||
"file_pdf_application_pdf.pdf^headers^",
|
||||
]
|
||||
|
||||
["browser_pdf_sandboxed_iframe.js"]
|
||||
support-files = ["file_pdf.pdf"]
|
||||
|
||||
["browser_pdf_save_as.js"]
|
||||
|
||||
["browser_protocol_ask_dialog.js"]
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { DownloadIntegration } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/DownloadIntegration.sys.mjs"
|
||||
);
|
||||
|
||||
const HandlerService = Cc[
|
||||
"@mozilla.org/uriloader/handler-service;1"
|
||||
].getService(Ci.nsIHandlerService);
|
||||
const MIMEService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
|
||||
const TEST_PATH = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"https://example.com"
|
||||
);
|
||||
|
||||
const { saveToDisk, alwaysAsk, handleInternally, useSystemDefault } =
|
||||
Ci.nsIHandlerInfo;
|
||||
|
||||
add_setup(async function () {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.download.always_ask_before_handling_new_types", false],
|
||||
["browser.download.useDownloadDir", false],
|
||||
],
|
||||
});
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
let publicList = await Downloads.getList(Downloads.PUBLIC);
|
||||
await publicList.removeFinished();
|
||||
|
||||
if (DownloadsPanel.isVisible) {
|
||||
let hiddenPromise = BrowserTestUtils.waitForEvent(
|
||||
DownloadsPanel.panel,
|
||||
"popuphidden"
|
||||
);
|
||||
DownloadsPanel.hidePanel();
|
||||
await hiddenPromise;
|
||||
}
|
||||
|
||||
let mimeInfo = MIMEService.getFromTypeAndExtension(
|
||||
"application/pdf",
|
||||
"pdf"
|
||||
);
|
||||
let existed = HandlerService.exists(mimeInfo);
|
||||
if (existed) {
|
||||
HandlerService.store(mimeInfo);
|
||||
} else {
|
||||
HandlerService.remove(mimeInfo);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function onFilePickerShown(test) {
|
||||
const { MockFilePicker } = SpecialPowers;
|
||||
|
||||
MockFilePicker.init(window.browsingContext);
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
|
||||
const promise = new Promise(resolve => {
|
||||
MockFilePicker.showCallback = fp => {
|
||||
ok(true, "filepicker should be visible");
|
||||
Assert.strictEqual(
|
||||
fp.defaultExtension,
|
||||
"pdf",
|
||||
"Default extension in filepicker should be pdf"
|
||||
);
|
||||
Assert.strictEqual(
|
||||
fp.defaultString,
|
||||
"file_pdf.pdf",
|
||||
"Default string name in filepicker should have the correct pdf file name"
|
||||
);
|
||||
setTimeout(resolve, 0);
|
||||
return Ci.nsIFilePicker.returnCancel;
|
||||
};
|
||||
});
|
||||
|
||||
test();
|
||||
|
||||
await promise;
|
||||
MockFilePicker.reset();
|
||||
}
|
||||
|
||||
function waitForAcceptButtonToGetEnabled(doc) {
|
||||
let dialog = doc.querySelector("#unknownContentType");
|
||||
let button = dialog.getButton("accept");
|
||||
return TestUtils.waitForCondition(
|
||||
() => !button.disabled,
|
||||
"Wait for Accept button to get enabled"
|
||||
);
|
||||
}
|
||||
|
||||
async function onExternalApplication(test) {
|
||||
let loaded = BrowserTestUtils.domWindowOpenedAndLoaded();
|
||||
test();
|
||||
const win = await loaded;
|
||||
is(
|
||||
win.location.href,
|
||||
"chrome://mozapps/content/downloads/unknownContentType.xhtml",
|
||||
"Should have seen the unknown content dialogWindow."
|
||||
);
|
||||
|
||||
const doc = win.document;
|
||||
await waitForAcceptButtonToGetEnabled(doc);
|
||||
const dialog = doc.querySelector("#unknownContentType");
|
||||
dialog.cancelDialog();
|
||||
}
|
||||
|
||||
async function onDownload(test) {
|
||||
const downloadsList = await Downloads.getList(Downloads.PUBLIC);
|
||||
const savePromise = promiseDownloadFinished(downloadsList, true);
|
||||
test();
|
||||
await savePromise;
|
||||
ok(true, "Download finished");
|
||||
}
|
||||
|
||||
async function onBlockedBySandbox(test) {
|
||||
const expected = `Download of “${TEST_PATH}file_pdf.pdf” was blocked because the triggering iframe has the sandbox flag set.`;
|
||||
return new Promise(resolve => {
|
||||
Services.console.registerListener(function onMessage(msg) {
|
||||
let { message, logLevel } = msg;
|
||||
if (logLevel != Ci.nsIConsoleMessage.warn) {
|
||||
return;
|
||||
}
|
||||
if (!message.includes(expected)) {
|
||||
return;
|
||||
}
|
||||
Services.console.unregisterListener(onMessage);
|
||||
resolve();
|
||||
});
|
||||
|
||||
test();
|
||||
});
|
||||
}
|
||||
|
||||
function autopass(test) {
|
||||
ok(true);
|
||||
test();
|
||||
}
|
||||
|
||||
const tests = [
|
||||
{
|
||||
preferredAction: alwaysAsk,
|
||||
runTest: onExternalApplication,
|
||||
header: "preferredAction = alwaysAsk",
|
||||
},
|
||||
{
|
||||
preferredAction: saveToDisk,
|
||||
runTest: onFilePickerShown,
|
||||
header: "preferredAction = saveToDisk",
|
||||
},
|
||||
{
|
||||
preferredAction: handleInternally,
|
||||
runTest: onBlockedBySandbox,
|
||||
header: "preferredAction = handleInternally",
|
||||
},
|
||||
{
|
||||
preferredAction: useSystemDefault,
|
||||
runTest: onDownload,
|
||||
header: "preferredAction = useSystemDefault",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* Tests that selecting the context menu item `Save Link As…` on a PDF link
|
||||
* opens the file picker when always_ask_before_handling_new_types is disabled,
|
||||
* regardless of preferredAction.
|
||||
*/
|
||||
add_task(async function test_pdf_save_as_link() {
|
||||
let mimeInfo;
|
||||
|
||||
for (let { preferredAction, runTest, header } of tests) {
|
||||
mimeInfo = MIMEService.getFromTypeAndExtension("application/pdf", "pdf");
|
||||
mimeInfo.alwaysAskBeforeHandling = preferredAction === alwaysAsk;
|
||||
mimeInfo.preferredAction = preferredAction;
|
||||
HandlerService.store(mimeInfo);
|
||||
|
||||
info(`Running test: ${header}`);
|
||||
|
||||
await runTest(() => {
|
||||
gBrowser.selectedTab = BrowserTestUtils.addTab(
|
||||
gBrowser,
|
||||
`data:text/html,<!doctype html><iframe sandbox="allow-downloads" src=${TEST_PATH}file_pdf.pdf></iframe>`
|
||||
);
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
});
|
||||
0
uriloader/exthandler/tests/mochitest/file_pdf.pdf
Normal file
0
uriloader/exthandler/tests/mochitest/file_pdf.pdf
Normal file
Reference in New Issue
Block a user