From 2187d372789d4d52db1216a8f3cf28f3580d681a Mon Sep 17 00:00:00 2001 From: Andrew Swan Date: Tue, 31 May 2016 11:42:41 -0700 Subject: [PATCH] Bug 1271345 Fix brower.download.download() on blob: urls r=kmag Calling download() on a blob URL was failing in schema validation since we weren't propagating the extension principal all the way to the call to scriptSecurityManager.checkLoadURI... MozReview-Commit-ID: JgEnQ6yxO4P --HG-- extra : rebase_source : d84933237e301c13ba34221c092b1e895acc20db --- toolkit/components/extensions/Extension.jsm | 4 ++ .../components/extensions/ext-downloads.js | 9 ++++- .../test_chrome_ext_downloads_download.html | 38 +++++++++++++++++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/toolkit/components/extensions/Extension.jsm b/toolkit/components/extensions/Extension.jsm index f7d021a09351..45a27f5f5149 100644 --- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -546,6 +546,10 @@ GlobalManager = { schemaApi.extensionTypes = {}; let schemaWrapper = { + get principal() { + return context.principal; + }, + get cloneScope() { return context.cloneScope; }, diff --git a/toolkit/components/extensions/ext-downloads.js b/toolkit/components/extensions/ext-downloads.js index de4293c665cb..4e144b8b05e8 100644 --- a/toolkit/components/extensions/ext-downloads.js +++ b/toolkit/components/extensions/ext-downloads.js @@ -420,8 +420,13 @@ extensions.registerSchemaAPI("downloads", "downloads", (extension, context) => { if (options.filename) { target = OS.Path.join(downloadsDir, options.filename); } else { - let uri = NetUtil.newURI(options.url).QueryInterface(Ci.nsIURL); - target = OS.Path.join(downloadsDir, uri.fileName); + let uri = NetUtil.newURI(options.url); + + let filename; + if (uri instanceof Ci.nsIURL) { + filename = uri.fileName; + } + target = OS.Path.join(downloadsDir, filename || "download"); } // This has a race, something else could come along and create diff --git a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_download.html b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_download.html index 54f1c16e7a7d..c3e79f817017 100644 --- a/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_download.html +++ b/toolkit/components/extensions/test/mochitest/test_chrome_ext_downloads_download.html @@ -51,13 +51,29 @@ function setup() { } function backgroundScript() { - browser.test.onMessage.addListener(function(msg) { + let blobUrl; + browser.test.onMessage.addListener((msg, ...args) => { if (msg == "download.request") { + let options = args[0]; + + if (options.blobme) { + let blob = new Blob(options.blobme); + delete options.blobme; + blobUrl = options.url = window.URL.createObjectURL(blob); + } + // download() throws on bad arguments, we can remove the extra // promise when bug 1250223 is fixed. - return Promise.resolve().then(() => browser.downloads.download(arguments[1])) - .then((id) => browser.test.sendMessage("download.done", {status: "success", id})) - .catch(error => browser.test.sendMessage("download.done", {status: "error", errmsg: error.message})); + return Promise.resolve().then(() => browser.downloads.download(options)) + .then(id => { + browser.test.sendMessage("download.done", {status: "success", id}); + }) + .catch(error => { + browser.test.sendMessage("download.done", {status: "error", errmsg: error.message}); + }); + } else if (msg == "killTheBlob") { + window.URL.revokeObjectURL(blobUrl); + blobUrl = null; } }); @@ -200,6 +216,20 @@ add_task(function* test_downloads() { is(msg.errmsg, "filename must not contain back-references (..)", "error message for back-references is correct"); }); + // Try to download a blob url + const BLOB_STRING = "Hello, world"; + yield testDownload({ + blobme: [BLOB_STRING], + filename: FILE_NAME, + }, FILE_NAME, BLOB_STRING.length, "blob url"); + extension.sendMessage("killTheBlob"); + + // Try to download a blob url without a given filename + yield testDownload({ + blobme: [BLOB_STRING], + }, "download", BLOB_STRING.length, "blob url with no filename"); + extension.sendMessage("killTheBlob"); + yield extension.unload(); });