From ce13019950a4113012714edfa34134acb1a2d61e Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Tue, 21 Mar 2017 11:11:06 +0100 Subject: [PATCH] Bug 1344957 - Enabling File.createFromNsIFile and File.createFromFileName only for testing and file-content-process, r=ehsan, r=bobowen --- dom/base/test/chrome/test_bug914381.html | 7 ++++++- dom/base/test/chrome/test_fileconstructor.xul | 6 +++++- dom/file/FileCreatorHelper.cpp | 15 +++++++++++++++ dom/ipc/ContentParent.cpp | 8 ++++++++ dom/webidl/File.webidl | 6 +++++- testing/marionette/driver.js | 2 ++ 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/dom/base/test/chrome/test_bug914381.html b/dom/base/test/chrome/test_bug914381.html index c40744637b86..26dc5379a092 100644 --- a/dom/base/test/chrome/test_bug914381.html +++ b/dom/base/test/chrome/test_bug914381.html @@ -35,7 +35,12 @@ function createFileWithData(fileData) { /** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/ var file = createFileWithData("Test bug 914381"); -File.createFromNsIFile(file).then(f => { + +SpecialPowers.pushPrefEnv({ set: [ "dom.file.createInChild" ]}) +.then(() => { + return File.createFromNsIFile(file); +}) +.then(f => { is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js"); is(f.mozFullPath, file.path, "mozFullPath returns path if created with nsIFile"); }) diff --git a/dom/base/test/chrome/test_fileconstructor.xul b/dom/base/test/chrome/test_fileconstructor.xul index 5cfcab301d80..7aeedd8ce016 100644 --- a/dom/base/test/chrome/test_fileconstructor.xul +++ b/dom/base/test/chrome/test_fileconstructor.xul @@ -42,7 +42,11 @@ file.append("test"); file.append("chrome"); file.append("fileconstructor_file.png"); -File.createFromFileName(file.path).then(function(domFile) { +SpecialPowers.pushPrefEnv({ set: [ "dom.file.createInChild" ]}) +.then(() => { + return File.createFromFileName(file.path); +}) +.then(function(domFile) { ok(domfile instanceof File, "File() should return a File"); is(domfile.type, "image/png", "File should be a PNG"); is(domfile.size, 95, "File has size 95 (and more importantly we can read it)"); diff --git a/dom/file/FileCreatorHelper.cpp b/dom/file/FileCreatorHelper.cpp index 72872a450d0a..dd8848a7608a 100644 --- a/dom/file/FileCreatorHelper.cpp +++ b/dom/file/FileCreatorHelper.cpp @@ -8,6 +8,7 @@ #include "mozilla/dom/BindingDeclarations.h" #include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/ContentParent.h" #include "mozilla/dom/FileBinding.h" #include "mozilla/dom/File.h" #include "mozilla/dom/Promise.h" @@ -54,6 +55,20 @@ FileCreatorHelper::CreateFile(nsIGlobalObject* aGlobalObject, // Content process. + ContentChild* cc = ContentChild::GetSingleton(); + if (!cc) { + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); + return promise.forget(); + } + + if (!cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE) && + !Preferences::GetBool("dom.file.createInChild", false)) { + // If this pref is not set and the request is received by the parent + // process, this child is killed for security reason. + promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); + return promise.forget(); + } + RefPtr helper = new FileCreatorHelper(promise, window); // The request is sent to the parent process and it's kept alive by diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 75e89b6aa5e5..38de6f20a464 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -5230,6 +5230,14 @@ ContentParent::RecvFileCreationRequest(const nsID& aID, const bool& aExistenceCheck, const bool& aIsFromNsIFile) { + // We allow the creation of File via this IPC call only for the 'file' process + // or for testing. + if (!mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE) && + !Preferences::GetBool("dom.file.createInChild", false)) { + KillHard("FileCreationRequest is not supported."); + return IPC_FAIL_NO_REASON(this); + } + RefPtr blobImpl; nsresult rv = FileCreatorHelper::CreateBlobImplForIPC(aFullPath, aType, aName, diff --git a/dom/webidl/File.webidl b/dom/webidl/File.webidl index 3c54a30dc04a..74b55951a5ae 100644 --- a/dom/webidl/File.webidl +++ b/dom/webidl/File.webidl @@ -41,7 +41,11 @@ partial interface File { readonly attribute DOMString mozFullPath; }; -// Mozilla extensions - main-thread only +// Mozilla extensions +// These 2 methods can be used only in these conditions: +// - the main-thread +// - parent process OR file process OR, only for testing, with pref +// `dom.file.createInChild' set to true. [Exposed=(Window)] partial interface File { [ChromeOnly, Throws, NeedsCallerType] diff --git a/testing/marionette/driver.js b/testing/marionette/driver.js index cf080e5b5d2e..d8d3ab5fe449 100644 --- a/testing/marionette/driver.js +++ b/testing/marionette/driver.js @@ -414,6 +414,8 @@ GeckoDriver.prototype.whenBrowserStarted = function (win, isNewSession) { // opened after this call mm.loadFrameScript(FRAME_SCRIPT, true); Preferences.set(CONTENT_LISTENER_PREF, true); + + Preferences.set("dom.file.createInChild", true); } } else { logger.error(