Backed out changeset 22c00a19e267 (bug 1534712) for causing test_bug536567_perwindowpb.html, browser_jsonview_save_json.js, browser_bookmark_backup_export_import.js to perma fail CLOSED TREE

This commit is contained in:
Ciure Andrei 2019-04-19 05:57:19 +03:00
Родитель add7a3fb9e
Коммит d13f7bbf24
25 изменённых файлов: 440 добавлений и 469 удалений

Просмотреть файл

@ -22,9 +22,8 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile)
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), EmptyString(),
EmptyString(), UINT64_MAX, INT64_MAX),
mFile(aFile),
mFileId(-1),
mWholeFile(true),
mHasEmptyMozFullPath(false) {
mFileId(-1) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
// Lazily get the content type and size
@ -38,9 +37,8 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType,
aLength, UINT64_MAX),
mFile(aFile),
mFileId(-1),
mWholeFile(true),
mHasEmptyMozFullPath(false) {
mFileId(-1) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
}
@ -51,9 +49,8 @@ FileBlobImpl::FileBlobImpl(const nsAString& aName,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aName, aContentType,
aLength, aLastModificationDate),
mFile(aFile),
mFileId(-1),
mWholeFile(true),
mHasEmptyMozFullPath(false) {
mFileId(-1) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
}
@ -63,9 +60,8 @@ FileBlobImpl::FileBlobImpl(nsIFile* aFile, const nsAString& aName,
const nsAString& aBlobImplType)
: BaseBlobImpl(aBlobImplType, aName, aContentType, UINT64_MAX, INT64_MAX),
mFile(aFile),
mFileId(-1),
mWholeFile(true),
mHasEmptyMozFullPath(false) {
mFileId(-1) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
if (aContentType.IsEmpty()) {
@ -79,9 +75,8 @@ FileBlobImpl::FileBlobImpl(const FileBlobImpl* aOther, uint64_t aStart,
: BaseBlobImpl(NS_LITERAL_STRING("FileBlobImpl"), aContentType,
aOther->mStart + aStart, aLength),
mFile(aOther->mFile),
mFileId(-1),
mWholeFile(false),
mHasEmptyMozFullPath(false) {
mFileId(-1) {
MOZ_ASSERT(mFile, "must have file");
MOZ_ASSERT(XRE_IsParentProcess());
mImmutable = aOther->mImmutable;
@ -97,12 +92,6 @@ already_AddRefed<BlobImpl> FileBlobImpl::CreateSlice(
void FileBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv) const {
MOZ_ASSERT(mIsFile, "Should only be called on files");
if (mHasEmptyMozFullPath) {
aFilename.Truncate();
return;
}
aRv = mFile->GetPath(aFilename);
}
@ -216,6 +205,10 @@ int64_t FileBlobImpl::GetLastModified(ErrorResult& aRv) {
return mLastModificationDate;
}
void FileBlobImpl::SetLastModified(int64_t aLastModified) {
MOZ_CRASH("SetLastModified of a real file is not allowed!");
}
const uint32_t sFileStreamFlags =
nsIFileInputStream::CLOSE_ON_EOF | nsIFileInputStream::REOPEN_ON_REWIND |
nsIFileInputStream::DEFER_OPEN | nsIFileInputStream::SHARE_DELETE;

Просмотреть файл

@ -37,6 +37,7 @@ class FileBlobImpl : public BaseBlobImpl {
virtual uint64_t GetSize(ErrorResult& aRv) override;
virtual void GetType(nsAString& aType) override;
virtual int64_t GetLastModified(ErrorResult& aRv) override;
virtual void SetLastModified(int64_t aLastModified) override;
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) const override;
virtual void CreateInputStream(nsIInputStream** aInputStream,
@ -56,8 +57,6 @@ class FileBlobImpl : public BaseBlobImpl {
void SetFileId(int64_t aFileId) { mFileId = aFileId; }
void SetEmptyMozFullPath() { mHasEmptyMozFullPath = true; }
protected:
virtual ~FileBlobImpl() = default;
@ -71,13 +70,8 @@ class FileBlobImpl : public BaseBlobImpl {
ErrorResult& aRv) override;
nsCOMPtr<nsIFile> mFile;
int64_t mFileId;
bool mWholeFile;
// When this is set to true, mozFullPath is returned as an empty string. This
// is useful in case the file doesn't exist (yet). See:
// FileCreatorHelper::CreateFile and aExistenceCheck.
bool mHasEmptyMozFullPath;
int64_t mFileId;
};
} // namespace dom

Просмотреть файл

@ -7,16 +7,13 @@
#include "FileCreatorHelper.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/FileBinding.h"
#include "mozilla/dom/ipc/FileCreatorChild.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/StaticPrefs.h"
#include "nsContentUtils.h"
#include "nsPIDOMWindow.h"
#include "nsProxyRelease.h"
#include "nsIFile.h"
// Undefine the macro of CreateFile to avoid FileCreatorHelper#CreateFile being
@ -39,32 +36,167 @@ already_AddRefed<Promise> FileCreatorHelper::CreateFile(
return nullptr;
}
nsAutoString path;
aRv = aFile->GetPath(path);
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobalObject);
// Parent process
if (XRE_IsParentProcess()) {
RefPtr<File> file =
CreateFileInternal(window, aFile, aBag, aIsFromNsIFile, aRv);
if (aRv.Failed()) {
return nullptr;
}
promise->MaybeResolve(file);
return promise.forget();
}
// 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<FileCreatorHelper> helper = new FileCreatorHelper(promise, window);
// The request is sent to the parent process and it's kept alive by
// ContentChild.
helper->SendRequest(aFile, aBag, aIsFromNsIFile, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
// Register this component to PBackground.
mozilla::ipc::PBackgroundChild* actorChild =
mozilla::ipc::BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!actorChild)) {
aRv.Throw(NS_ERROR_FAILURE);
return promise.forget();
}
/* static */
already_AddRefed<File> FileCreatorHelper::CreateFileInternal(
nsPIDOMWindowInner* aWindow, nsIFile* aFile,
const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv) {
bool lastModifiedPassed = false;
int64_t lastModified = 0;
if (aBag.mLastModified.WasPassed()) {
lastModifiedPassed = true;
lastModified = aBag.mLastModified.Value();
}
RefPtr<BlobImpl> blobImpl;
aRv = CreateBlobImpl(aFile, aBag.mType, aBag.mName, lastModifiedPassed,
lastModified, aBag.mExistenceCheck, aIsFromNsIFile,
getter_AddRefs(blobImpl));
if (aRv.Failed()) {
return nullptr;
}
Maybe<int64_t> lastModified;
if (aBag.mLastModified.WasPassed()) {
lastModified.emplace(aBag.mLastModified.Value());
RefPtr<File> file = File::Create(aWindow, blobImpl);
return file.forget();
}
FileCreatorHelper::FileCreatorHelper(Promise* aPromise,
nsPIDOMWindowInner* aWindow)
: mPromise(aPromise), mWindow(aWindow) {
MOZ_ASSERT(aPromise);
}
FileCreatorHelper::~FileCreatorHelper() {}
void FileCreatorHelper::SendRequest(nsIFile* aFile,
const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile, ErrorResult& aRv) {
MOZ_ASSERT(aFile);
ContentChild* cc = ContentChild::GetSingleton();
if (NS_WARN_IF(!cc)) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
mozilla::ipc::PFileCreatorChild* actor =
actorChild->SendPFileCreatorConstructor(
path, aBag.mType, aBag.mName, lastModified, aBag.mExistenceCheck,
aIsFromNsIFile);
nsID uuid;
aRv = nsContentUtils::GenerateUUIDInPlace(uuid);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
static_cast<FileCreatorChild*>(actor)->SetPromise(promise);
return promise.forget();
nsAutoString path;
aRv = aFile->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
cc->FileCreationRequest(uuid, this, path, aBag.mType, aBag.mName,
aBag.mLastModified, aBag.mExistenceCheck,
aIsFromNsIFile);
}
void FileCreatorHelper::ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv) {
if (NS_FAILED(aRv)) {
mPromise->MaybeReject(aRv);
return;
}
RefPtr<File> file = File::Create(mWindow, aBlobImpl);
mPromise->MaybeResolve(file);
}
/* static */
nsresult FileCreatorHelper::CreateBlobImplForIPC(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return CreateBlobImpl(file, aType, aName, aLastModifiedPassed, aLastModified,
aExistenceCheck, aIsFromNsIFile, aBlobImpl);
}
/* static */
nsresult FileCreatorHelper::CreateBlobImpl(
nsIFile* aFile, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
if (!aExistenceCheck) {
RefPtr<FileBlobImpl> impl = new FileBlobImpl(aFile);
if (!aName.IsEmpty()) {
impl->SetName(aName);
}
if (!aType.IsEmpty()) {
impl->SetType(aType);
}
if (aLastModifiedPassed) {
impl->SetLastModified(aLastModified);
}
impl.forget(aBlobImpl);
return NS_OK;
}
RefPtr<MultipartBlobImpl> impl = new MultipartBlobImpl(EmptyString());
nsresult rv = impl->InitializeChromeFile(
aFile, aType, aName, aLastModifiedPassed, aLastModified, aIsFromNsIFile);
if (NS_FAILED(rv)) {
return rv;
}
MOZ_ASSERT(impl->IsFile());
impl.forget(aBlobImpl);
return NS_OK;
}
} // namespace dom

Просмотреть файл

@ -20,20 +20,52 @@
class nsIFile;
class nsIGlobalObject;
class nsPIDOMWindowInner;
namespace mozilla {
namespace dom {
struct ChromeFilePropertyBag;
class Promise;
class File;
class FileCreatorHelper final {
public:
NS_INLINE_DECL_REFCOUNTING(FileCreatorHelper);
static already_AddRefed<Promise> CreateFile(nsIGlobalObject* aGlobalObject,
nsIFile* aFile,
const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile,
ErrorResult& aRv);
void ResponseReceived(BlobImpl* aBlobImpl, nsresult aRv);
// For IPC only
static nsresult CreateBlobImplForIPC(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
private:
static already_AddRefed<File> CreateFileInternal(
nsPIDOMWindowInner* aWindow, nsIFile* aFile,
const ChromeFilePropertyBag& aBag, bool aIsFromNsIFile, ErrorResult& aRv);
static nsresult CreateBlobImpl(nsIFile* aFile, const nsAString& aType,
const nsAString& aName,
bool aLastModifiedPassed,
int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
FileCreatorHelper(Promise* aPromise, nsPIDOMWindowInner* aWindow);
~FileCreatorHelper();
void SendRequest(nsIFile* aFile, const ChromeFilePropertyBag& aBag,
bool aIsFromNsIFile, ErrorResult& aRv);
RefPtr<Promise> mPromise;
nsCOMPtr<nsPIDOMWindowInner> mWindow;
};
} // namespace dom

Просмотреть файл

@ -274,6 +274,22 @@ void MultipartBlobImpl::SetLengthAndModifiedDate(ErrorResult& aRv) {
}
}
void MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
ErrorResult& aRv) const {
if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
BaseBlobImpl::GetMozFullPathInternal(aFilename, aRv);
return;
}
BlobImpl* blobImpl = mBlobImpls.ElementAt(0).get();
if (!blobImpl) {
BaseBlobImpl::GetMozFullPathInternal(aFilename, aRv);
return;
}
blobImpl->GetMozFullPathInternal(aFilename, aRv);
}
nsresult MultipartBlobImpl::SetMutable(bool aMutable) {
nsresult rv;
@ -301,6 +317,82 @@ nsresult MultipartBlobImpl::SetMutable(bool aMutable) {
return NS_OK;
}
nsresult MultipartBlobImpl::InitializeChromeFile(
nsIFile* aFile, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aIsFromNsIFile) {
MOZ_ASSERT(!mImmutable, "Something went wrong ...");
if (mImmutable) {
return NS_ERROR_UNEXPECTED;
}
mName = aName;
mContentType = aType;
mIsFromNsIFile = aIsFromNsIFile;
bool exists;
nsresult rv = aFile->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
return NS_ERROR_FILE_NOT_FOUND;
}
bool isDir;
rv = aFile->IsDirectory(&isDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDir) {
return NS_ERROR_FILE_IS_DIRECTORY;
}
if (mName.IsEmpty()) {
aFile->GetLeafName(mName);
}
RefPtr<File> blob = File::CreateFromFile(nullptr, aFile);
// Pre-cache size.
ErrorResult error;
blob->GetSize(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// Pre-cache modified date.
blob->GetLastModified(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
// XXXkhuey this is terrible
if (mContentType.IsEmpty()) {
blob->GetType(mContentType);
}
BlobSet blobSet;
rv = blobSet.AppendBlobImpl(static_cast<File*>(blob.get())->Impl());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mBlobImpls = blobSet.GetBlobImpls();
SetLengthAndModifiedDate(error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
if (aLastModifiedPassed) {
SetLastModified(aLastModified);
}
return NS_OK;
}
bool MultipartBlobImpl::MayBeClonedToOtherThreads() const {
for (uint32_t i = 0; i < mBlobImpls.Length(); ++i) {
if (!mBlobImpls[i]->MayBeClonedToOtherThreads()) {

Просмотреть файл

@ -32,12 +32,14 @@ class MultipartBlobImpl final : public BaseBlobImpl {
// Create as a file to be later initialized
explicit MultipartBlobImpl(const nsAString& aName)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aName,
EmptyString(), UINT64_MAX) {}
EmptyString(), UINT64_MAX),
mIsFromNsIFile(false) {}
// Create as a blob to be later initialized
MultipartBlobImpl()
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), EmptyString(),
UINT64_MAX) {}
UINT64_MAX),
mIsFromNsIFile(false) {}
void InitializeBlob(ErrorResult& aRv);
@ -45,6 +47,11 @@ class MultipartBlobImpl final : public BaseBlobImpl {
const nsAString& aContentType, bool aNativeEOL,
ErrorResult& aRv);
nsresult InitializeChromeFile(nsIFile* aData, const nsAString& aType,
const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified,
bool aIsFromNsIFile);
virtual already_AddRefed<BlobImpl> CreateSlice(uint64_t aStart,
uint64_t aLength,
const nsAString& aContentType,
@ -59,6 +66,9 @@ class MultipartBlobImpl final : public BaseBlobImpl {
return mBlobImpls.Length() ? &mBlobImpls : nullptr;
}
virtual void GetMozFullPathInternal(nsAString& aFullPath,
ErrorResult& aRv) const override;
virtual nsresult SetMutable(bool aMutable) override;
void SetName(const nsAString& aName) { mName = aName; }
@ -76,19 +86,22 @@ class MultipartBlobImpl final : public BaseBlobImpl {
const nsAString& aName, const nsAString& aContentType)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aName,
aContentType, UINT64_MAX),
mBlobImpls(std::move(aBlobImpls)) {}
mBlobImpls(std::move(aBlobImpls)),
mIsFromNsIFile(false) {}
MultipartBlobImpl(nsTArray<RefPtr<BlobImpl>>&& aBlobImpls,
const nsAString& aContentType)
: BaseBlobImpl(NS_LITERAL_STRING("MultipartBlobImpl"), aContentType,
UINT64_MAX),
mBlobImpls(std::move(aBlobImpls)) {}
mBlobImpls(std::move(aBlobImpls)),
mIsFromNsIFile(false) {}
virtual ~MultipartBlobImpl() {}
void SetLengthAndModifiedDate(ErrorResult& aRv);
nsTArray<RefPtr<BlobImpl>> mBlobImpls;
bool mIsFromNsIFile;
};
} // namespace dom

Просмотреть файл

@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FileCreatorChild.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/IPCBlobUtils.h"
namespace mozilla {
namespace dom {
FileCreatorChild::FileCreatorChild() = default;
FileCreatorChild::~FileCreatorChild() { MOZ_ASSERT(!mPromise); }
void FileCreatorChild::SetPromise(Promise* aPromise) {
MOZ_ASSERT(aPromise);
MOZ_ASSERT(!mPromise);
mPromise = aPromise;
}
mozilla::ipc::IPCResult FileCreatorChild::Recv__delete__(
const FileCreationResult& aResult) {
MOZ_ASSERT(mPromise);
RefPtr<Promise> promise;
promise.swap(mPromise);
if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
promise->MaybeReject(aResult.get_FileCreationErrorResult().errorCode());
return IPC_OK();
}
MOZ_ASSERT(aResult.type() == FileCreationResult::TFileCreationSuccessResult);
RefPtr<dom::BlobImpl> impl = dom::IPCBlobUtils::Deserialize(
aResult.get_FileCreationSuccessResult().blob());
RefPtr<File> file = File::Create(promise->GetParentObject(), impl);
promise->MaybeResolve(file);
return IPC_OK();
}
void FileCreatorChild::ActorDestroy(ActorDestroyReason aWhy) {
if (mPromise) {
mPromise->MaybeReject(NS_ERROR_FAILURE);
mPromise = nullptr;
}
};
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,36 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ipc_FileCreatorChild_h
#define mozilla_dom_ipc_FileCreatorChild_h
#include "mozilla/ipc/PFileCreatorChild.h"
namespace mozilla {
namespace dom {
class FileCreatorChild final : public mozilla::ipc::PFileCreatorChild {
friend class mozilla::ipc::PFileCreatorChild;
public:
FileCreatorChild();
~FileCreatorChild();
void SetPromise(Promise* aPromise);
private:
mozilla::ipc::IPCResult Recv__delete__(
const FileCreationResult& aResult) override;
void ActorDestroy(ActorDestroyReason aWhy) override;
RefPtr<Promise> mPromise;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_FileCreatorChild_h

Просмотреть файл

@ -1,128 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FileCreatorParent.h"
#include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/MultipartBlobImpl.h"
namespace mozilla {
namespace dom {
FileCreatorParent::FileCreatorParent()
: mBackgroundEventTarget(GetCurrentThreadEventTarget()), mIPCActive(true) {}
FileCreatorParent::~FileCreatorParent() = default;
mozilla::ipc::IPCResult FileCreatorParent::CreateAndShareFile(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
RefPtr<dom::BlobImpl> blobImpl;
nsresult rv =
CreateBlobImpl(aFullPath, aType, aName, aLastModified.isSome(),
aLastModified.isSome() ? aLastModified.value() : 0,
aExistenceCheck, aIsFromNsIFile, getter_AddRefs(blobImpl));
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(this, FileCreationErrorResult(rv));
return IPC_OK();
}
MOZ_ASSERT(blobImpl);
// FileBlobImpl is unable to return the correct type on this thread because
// nsIMIMEService is not thread-safe. We must exec the 'type' getter on
// main-thread before send the blob to the child actor.
RefPtr<FileCreatorParent> self = this;
NS_DispatchToMainThread(NS_NewRunnableFunction(
"FileCreatorParent::CreateAndShareFile", [self, blobImpl]() {
nsAutoString type;
blobImpl->GetType(type);
self->mBackgroundEventTarget->Dispatch(NS_NewRunnableFunction(
"FileCreatorParent::CreateAndShareFile return", [self, blobImpl]() {
if (self->mIPCActive) {
IPCBlob ipcBlob;
nsresult rv = dom::IPCBlobUtils::Serialize(
blobImpl, self->Manager(), ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
Unused << Send__delete__(self, FileCreationErrorResult(rv));
return;
}
Unused << Send__delete__(self,
FileCreationSuccessResult(ipcBlob));
}
}));
}));
return IPC_OK();
}
void FileCreatorParent::ActorDestroy(ActorDestroyReason aWhy) {
mIPCActive = false;
}
/* static */
nsresult FileCreatorParent::CreateBlobImpl(
const nsAString& aPath, const nsAString& aType, const nsAString& aName,
bool aLastModifiedPassed, int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl) {
MOZ_ASSERT(!NS_IsMainThread());
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(aPath, true, getter_AddRefs(file));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (aExistenceCheck) {
bool exists;
nsresult rv = file->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!exists) {
return NS_ERROR_FILE_NOT_FOUND;
}
bool isDir;
rv = file->IsDirectory(&isDir);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (isDir) {
return NS_ERROR_FILE_IS_DIRECTORY;
}
}
RefPtr<FileBlobImpl> impl = new FileBlobImpl(file);
if (!aName.IsEmpty()) {
impl->SetName(aName);
}
if (!aType.IsEmpty()) {
impl->SetType(aType);
}
if (aLastModifiedPassed) {
impl->SetLastModified(aLastModified);
}
if (!aIsFromNsIFile) {
impl->SetEmptyMozFullPath();
}
impl.forget(aBlobImpl);
return NS_OK;
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -1,47 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_ipc_FileCreatorParent_h
#define mozilla_dom_ipc_FileCreatorParent_h
#include "mozilla/ipc/PFileCreatorParent.h"
class nsIFile;
namespace mozilla {
namespace dom {
class BlobImpl;
class FileCreatorParent final : public mozilla::ipc::PFileCreatorParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileCreatorParent)
FileCreatorParent();
mozilla::ipc::IPCResult CreateAndShareFile(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile);
private:
~FileCreatorParent();
void ActorDestroy(ActorDestroyReason aWhy) override;
nsresult CreateBlobImpl(const nsAString& aPath, const nsAString& aType,
const nsAString& aName, bool aLastModifiedPassed,
int64_t aLastModified, bool aExistenceCheck,
bool aIsFromNsIFile, BlobImpl** aBlobImpl);
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
bool mIPCActive;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_FileCreatorParent_h

Просмотреть файл

@ -1,41 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBackground;
include protocol PChildToParentStream;
include protocol PFileDescriptorSet;
include protocol PIPCBlobInputStream;
include protocol PParentToChildStream;
include IPCBlob;
namespace mozilla {
namespace ipc {
struct FileCreationSuccessResult
{
IPCBlob blob;
};
struct FileCreationErrorResult
{
nsresult errorCode;
};
union FileCreationResult
{
FileCreationSuccessResult;
FileCreationErrorResult;
};
protocol PFileCreator
{
manager PBackground;
child:
async __delete__(FileCreationResult aResult);
};
} // namespace ipc
} // namespace mozilla

Просмотреть файл

@ -39,5 +39,5 @@ parent:
async OperationDone(nsCString aContentType, FileDescriptor aFD);
};
} // namespace ipc
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -8,8 +8,6 @@ with Files("**"):
BUG_COMPONENT = ("Core", "DOM: File")
EXPORTS.mozilla.dom.ipc += [
'FileCreatorChild.h',
'FileCreatorParent.h',
'IPCBlobInputStream.h',
'IPCBlobInputStreamChild.h',
'IPCBlobInputStreamParent.h',
@ -25,8 +23,6 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'FileCreatorChild.cpp',
'FileCreatorParent.cpp',
'IPCBlobInputStream.cpp',
'IPCBlobInputStreamChild.cpp',
'IPCBlobInputStreamParent.cpp',
@ -42,7 +38,6 @@ UNIFIED_SOURCES += [
IPDL_SOURCES += [
'BlobTypes.ipdlh',
'IPCBlob.ipdlh',
'PFileCreator.ipdl',
'PIPCBlobInputStream.ipdl',
'PPendingIPCBlob.ipdl',
'PTemporaryIPCBlob.ipdl',

Просмотреть файл

@ -39,6 +39,7 @@
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DocGroup.h"
#include "mozilla/dom/ExternalHelperAppChild.h"
#include "mozilla/dom/FileCreatorHelper.h"
#include "mozilla/dom/GetFilesHelper.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/JSWindowActorService.h"
@ -3387,6 +3388,51 @@ bool ContentChild::DeallocPSessionStorageObserverChild(
return true;
}
void ContentChild::FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
const nsAString& aFullPath,
const nsAString& aType,
const nsAString& aName,
const Optional<int64_t>& aLastModified,
bool aExistenceCheck,
bool aIsFromNsIFile) {
MOZ_ASSERT(aHelper);
bool lastModifiedPassed = false;
int64_t lastModified = 0;
if (aLastModified.WasPassed()) {
lastModifiedPassed = true;
lastModified = aLastModified.Value();
}
Unused << SendFileCreationRequest(
aUUID, nsString(aFullPath), nsString(aType), nsString(aName),
lastModifiedPassed, lastModified, aExistenceCheck, aIsFromNsIFile);
mFileCreationPending.Put(aUUID, aHelper);
}
mozilla::ipc::IPCResult ContentChild::RecvFileCreationResponse(
const nsID& aUUID, const FileCreationResult& aResult) {
FileCreatorHelper* helper = mFileCreationPending.GetWeak(aUUID);
if (!helper) {
return IPC_FAIL_NO_REASON(this);
}
if (aResult.type() == FileCreationResult::TFileCreationErrorResult) {
helper->ResponseReceived(nullptr,
aResult.get_FileCreationErrorResult().errorCode());
} else {
MOZ_ASSERT(aResult.type() ==
FileCreationResult::TFileCreationSuccessResult);
RefPtr<BlobImpl> impl = IPCBlobUtils::Deserialize(
aResult.get_FileCreationSuccessResult().blob());
helper->ResponseReceived(impl, NS_OK);
}
mFileCreationPending.Remove(aUUID);
return IPC_OK();
}
mozilla::ipc::IPCResult ContentChild::RecvActivate(PBrowserChild* aTab) {
TabChild* tab = static_cast<TabChild*>(aTab);
return tab->RecvActivate();

Просмотреть файл

@ -77,6 +77,7 @@ class ConsoleListener;
class ClonedMessageData;
class TabChild;
class GetFilesHelperChild;
class FileCreatorHelper;
class ContentChild final : public PContentChild,
public nsIWindowProvider,
@ -563,6 +564,9 @@ class ContentChild final : public PContentChild,
mozilla::ipc::IPCResult RecvBlobURLUnregistration(const nsCString& aURI);
mozilla::ipc::IPCResult RecvFileCreationResponse(
const nsID& aUUID, const FileCreationResult& aResult);
mozilla::ipc::IPCResult RecvRequestMemoryReport(
const uint32_t& generation, const bool& anonymize,
const bool& minimizeMemoryUsage, const Maybe<FileDescriptor>& DMDFile);
@ -641,6 +645,13 @@ class ContentChild final : public PContentChild,
static void FatalErrorIfNotUsingGPUProcess(const char* const aErrorMsg,
base::ProcessId aOtherPid);
// This method is used by FileCreatorHelper for the creation of a BlobImpl.
void FileCreationRequest(nsID& aUUID, FileCreatorHelper* aHelper,
const nsAString& aFullPath, const nsAString& aType,
const nsAString& aName,
const Optional<int64_t>& aLastModified,
bool aExistenceCheck, bool aIsFromNsIFile);
typedef std::function<void(PRFileDesc*)> AnonymousTemporaryFileCallback;
nsresult AsyncOpenAnonymousTemporaryFile(
const AnonymousTemporaryFileCallback& aCallback);
@ -792,6 +803,10 @@ class ContentChild final : public PContentChild,
// received.
nsRefPtrHashtable<nsIDHashKey, GetFilesHelperChild> mGetFilesPendingRequests;
// Hashtable to keep track of the pending file creation.
// These items are removed when RecvFileCreationResponse is received.
nsRefPtrHashtable<nsIDHashKey, FileCreatorHelper> mFileCreationPending;
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback>
mPendingAnonymousTemporaryFiles;

Просмотреть файл

@ -47,6 +47,7 @@
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileCreatorHelper.h"
#include "mozilla/dom/FileSystemSecurity.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/ExternalHelperAppParent.h"
@ -5532,6 +5533,49 @@ bool ContentParent::DeallocPSessionStorageObserverParent(
return mozilla::dom::DeallocPSessionStorageObserverParent(aActor);
}
mozilla::ipc::IPCResult ContentParent::RecvFileCreationRequest(
const nsID& aID, const nsString& aFullPath, const nsString& aType,
const nsString& aName, const bool& aLastModifiedPassed,
const int64_t& aLastModified, 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)) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<BlobImpl> blobImpl;
nsresult rv = FileCreatorHelper::CreateBlobImplForIPC(
aFullPath, aType, aName, aLastModifiedPassed, aLastModified,
aExistenceCheck, aIsFromNsIFile, getter_AddRefs(blobImpl));
if (NS_WARN_IF(NS_FAILED(rv))) {
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
MOZ_ASSERT(blobImpl);
IPCBlob ipcBlob;
rv = IPCBlobUtils::Serialize(blobImpl, this, ipcBlob);
if (NS_WARN_IF(NS_FAILED(rv))) {
if (!SendFileCreationResponse(aID, FileCreationErrorResult(rv))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
if (!SendFileCreationResponse(aID, FileCreationSuccessResult(ipcBlob))) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
nsresult ContentParent::SaveRecording(nsIFile* aFile, bool* aRetval) {
if (mRecordReplayState != eRecording) {
*aRetval = false;

Просмотреть файл

@ -1127,6 +1127,12 @@ class ContentParent final : public PContentParent,
mozilla::ipc::IPCResult RecvDeleteGetFilesRequest(const nsID& aID);
mozilla::ipc::IPCResult RecvFileCreationRequest(
const nsID& aID, const nsString& aFullPath, const nsString& aType,
const nsString& aName, const bool& aLastModifiedPassed,
const int64_t& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile);
mozilla::ipc::IPCResult RecvAccumulateChildHistograms(
InfallibleTArray<HistogramAccumulation>&& aAccumulations);
mozilla::ipc::IPCResult RecvAccumulateChildKeyedHistograms(

Просмотреть файл

@ -203,6 +203,22 @@ union GetFilesResponseResult
GetFilesResponseFailure;
};
struct FileCreationSuccessResult
{
IPCBlob blob;
};
struct FileCreationErrorResult
{
nsresult errorCode;
};
union FileCreationResult
{
FileCreationSuccessResult;
FileCreationErrorResult;
};
struct BlobURLRegistrationData
{
nsCString url;
@ -654,6 +670,8 @@ child:
async GMPsChanged(GMPCapabilityData[] capabilities);
async FileCreationResponse(nsID aID, FileCreationResult aResult);
/**
* Sending an activate message moves focus to the child.
*/
@ -1188,6 +1206,11 @@ parent:
async GetFilesRequest(nsID aID, nsString aDirectory, bool aRecursiveFlag);
async DeleteGetFilesRequest(nsID aID);
async FileCreationRequest(nsID aID, nsString aFullPath, nsString aType,
nsString aName, bool lastModifiedPassed,
int64_t lastModified, bool aExistenceCheck,
bool aIsFromNsIFile);
async StoreAndBroadcastBlobURLRegistration(nsCString url, IPCBlob blob,
Principal principal);

Просмотреть файл

@ -27,11 +27,9 @@
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
#include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
#include "mozilla/dom/ipc/FileCreatorChild.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
#include "mozilla/dom/ipc/PendingIPCBlobChild.h"
#include "mozilla/dom/ipc/TemporaryIPCBlobChild.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/quota/PQuotaChild.h"
#include "mozilla/dom/RemoteWorkerChild.h"
#include "mozilla/dom/RemoteWorkerServiceChild.h"
@ -381,18 +379,6 @@ bool BackgroundChildImpl::DeallocPTemporaryIPCBlobChild(
return true;
}
PFileCreatorChild* BackgroundChildImpl::AllocPFileCreatorChild(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
return new mozilla::dom::FileCreatorChild();
}
bool BackgroundChildImpl::DeallocPFileCreatorChild(PFileCreatorChild* aActor) {
delete static_cast<mozilla::dom::FileCreatorChild*>(aActor);
return true;
}
PIPCBlobInputStreamChild* BackgroundChildImpl::AllocPIPCBlobInputStreamChild(
const nsID& aID, const uint64_t& aSize) {
// IPCBlobInputStreamChild is refcounted. Here it's created and in

Просмотреть файл

@ -9,7 +9,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "nsRefPtrHashtable.h"
#include "nsAutoPtr.h"
namespace mozilla {
@ -127,13 +126,6 @@ class BackgroundChildImpl : public PBackgroundChild {
virtual bool DeallocPTemporaryIPCBlobChild(
PTemporaryIPCBlobChild* aActor) override;
virtual PFileCreatorChild* AllocPFileCreatorChild(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual bool DeallocPFileCreatorChild(PFileCreatorChild* aActor) override;
virtual mozilla::dom::PRemoteWorkerChild* AllocPRemoteWorkerChild(
const RemoteWorkerData& aData) override;

Просмотреть файл

@ -30,11 +30,9 @@
#include "mozilla/dom/StorageActivityService.h"
#include "mozilla/dom/cache/ActorUtils.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/ipc/FileCreatorParent.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
#include "mozilla/dom/ipc/PendingIPCBlobParent.h"
#include "mozilla/dom/ipc/TemporaryIPCBlobParent.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/localstorage/ActorsParent.h"
#include "mozilla/dom/quota/ActorsParent.h"
#include "mozilla/dom/simpledb/ActorsParent.h"
@ -58,7 +56,6 @@
#include "mozilla/dom/network/UDPSocketParent.h"
#include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/Preferences.h"
#include "mozilla/StaticPrefs.h"
#include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
#include "nsProxyRelease.h"
@ -541,53 +538,6 @@ bool BackgroundParentImpl::DeallocPSharedWorkerParent(
return true;
}
PFileCreatorParent* BackgroundParentImpl::AllocPFileCreatorParent(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
RefPtr<mozilla::dom::FileCreatorParent> actor =
new mozilla::dom::FileCreatorParent();
return actor.forget().take();
}
mozilla::ipc::IPCResult BackgroundParentImpl::RecvPFileCreatorConstructor(
PFileCreatorParent* aActor, const nsString& aFullPath,
const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) {
bool isFileRemoteType = false;
// If the ContentParent is null we are dealing with a same-process actor.
RefPtr<ContentParent> parent = BackgroundParent::GetContentParent(this);
if (!parent) {
isFileRemoteType = true;
} else {
isFileRemoteType = parent->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE);
NS_ReleaseOnMainThreadSystemGroup("ContentParent release", parent.forget());
}
mozilla::dom::FileCreatorParent* actor =
static_cast<mozilla::dom::FileCreatorParent*>(aActor);
// We allow the creation of File via this IPC call only for the 'file' process
// or for testing.
if (!isFileRemoteType && !StaticPrefs::dom_file_createInChild()) {
Unused << mozilla::dom::FileCreatorParent::Send__delete__(
actor, FileCreationErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return IPC_OK();
}
return actor->CreateAndShareFile(aFullPath, aType, aName, aLastModified,
aExistenceCheck, aIsFromNsIFile);
}
bool BackgroundParentImpl::DeallocPFileCreatorParent(
PFileCreatorParent* aActor) {
RefPtr<mozilla::dom::FileCreatorParent> actor =
dont_AddRef(static_cast<mozilla::dom::FileCreatorParent*>(aActor));
return true;
}
PTemporaryIPCBlobParent* BackgroundParentImpl::AllocPTemporaryIPCBlobParent() {
return new mozilla::dom::TemporaryIPCBlobParent();
}

Просмотреть файл

@ -155,19 +155,6 @@ class BackgroundParentImpl : public PBackgroundParent {
virtual bool DeallocPTemporaryIPCBlobParent(
PTemporaryIPCBlobParent* aActor) override;
virtual PFileCreatorParent* AllocPFileCreatorParent(
const nsString& aFullPath, const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual mozilla::ipc::IPCResult RecvPFileCreatorConstructor(
PFileCreatorParent* actor, const nsString& aFullPath,
const nsString& aType, const nsString& aName,
const Maybe<int64_t>& aLastModified, const bool& aExistenceCheck,
const bool& aIsFromNsIFile) override;
virtual bool DeallocPFileCreatorParent(PFileCreatorParent* aActor) override;
virtual mozilla::dom::PRemoteWorkerParent* AllocPRemoteWorkerParent(
const RemoteWorkerData& aData) override;

Просмотреть файл

@ -29,7 +29,6 @@ include protocol PRemoteWorker;
include protocol PRemoteWorkerService;
include protocol PSharedWorker;
include protocol PTemporaryIPCBlob;
include protocol PFileCreator;
include protocol PMessagePort;
include protocol PCameras;
include protocol PMIDIManager;
@ -95,7 +94,6 @@ sync protocol PBackground
manages PRemoteWorkerService;
manages PSharedWorker;
manages PTemporaryIPCBlob;
manages PFileCreator;
manages PMessagePort;
manages PCameras;
manages PMIDIManager;
@ -199,10 +197,6 @@ parent:
async PTemporaryIPCBlob();
async PFileCreator(nsString aFullPath, nsString aType, nsString aName,
int64_t? lastModified, bool aExistenceCheck,
bool aIsFromNsIFile);
async PClientManager();
async PMIDIManager();
@ -234,7 +228,6 @@ child:
async PPendingIPCBlob(IPCBlob blob);
async PRemoteWorker(RemoteWorkerData data);
both:
// PIPCBlobInputStream is created on the parent side only if the child starts
// a migration.

Просмотреть файл

@ -29,13 +29,6 @@ DIRECT_CALL_OVERRIDES = {
"RemotePermissionRequest", "nsContentPermissionHelper.h"
),
("PFileCreator", "child"): (
"mozilla::dom::FileCreatorChild", "mozilla/dom/ipc/FileCreatorChild.h"
),
("PFileCreator", "parent"): (
"mozilla::dom::FileCreatorParent", "mozilla/dom/ipc/FileCreatorParent.h"
),
("PFileSystemRequest", "child"): (
"FileSystemTaskChildBase", "mozilla/dom/FileSystemTaskBase.h"
),

Просмотреть файл

@ -572,14 +572,6 @@ VARCACHE_PREF(
bool, true
)
// Allow the content process to create a File from a path. This is allowed just
// on parent process, on 'file' Content process, or for testing.
VARCACHE_PREF(
"dom.file.createInChild",
dom_file_createInChild,
RelaxedAtomicBool, false
)
//---------------------------------------------------------------------------
// Extension prefs
//---------------------------------------------------------------------------