/* -*- 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 "mozilla/dom/FileSystemRequestParent.h"
#include "mozilla/dom/PFileSystemParams.h"
#include "GetDirectoryListingTask.h"
#include "GetFileOrDirectoryTask.h"
#include "GetFilesTask.h"
#include "mozilla/dom/BlobImpl.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemSecurity.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/dom/OSFileSystem.h"
#include "mozilla/Preferences.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/Unused.h"
#include "nsProxyRelease.h"
using namespace mozilla::ipc;
namespace mozilla::dom {
FileSystemRequestParent::FileSystemRequestParent() : mDestroyed(false ) {
AssertIsOnBackgroundThread();
}
FileSystemRequestParent::~FileSystemRequestParent() {
AssertIsOnBackgroundThread();
}
#define FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(name) \
case FileSystemParams::TFileSystem## name## Params: { \
const FileSystem## name## Params& p = aParams; \
mFileSystem = new OSFileSystemParent(p.filesystem()); \
MOZ_ASSERT(mFileSystem); \
mTask = name## TaskParent::Create(mFileSystem, p, this , rv); \
if (NS_WARN_IF(rv.Failed())) { \
rv.SuppressException(); \
return false ; \
} \
break ; \
}
bool FileSystemRequestParent::Initialize(const FileSystemParams& aParams) {
AssertIsOnBackgroundThread();
ErrorResult rv;
switch (aParams.type()) {
FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetDirectoryListing)
FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetFileOrDirectory)
FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetFiles)
default : {
MOZ_CRASH("not reached" );
break ;
}
}
if (NS_WARN_IF(!mTask || !mFileSystem)) {
// Should never reach here.
return false ;
}
return true ;
}
namespace {
class CheckPermissionRunnable final : public Runnable {
public :
CheckPermissionRunnable(
already_AddRefed<ThreadsafeContentParentHandle> aParent,
FileSystemRequestParent* aActor, FileSystemTaskParentBase* aTask,
const nsAString& aPath)
: Runnable("dom::CheckPermissionRunnable" ),
mContentHandle(aParent),
mActor(aActor),
mTask(aTask),
mPath(aPath),
mBackgroundEventTarget(GetCurrentSerialEventTarget()) {
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(mContentHandle);
MOZ_ASSERT(mActor);
MOZ_ASSERT(mTask);
MOZ_ASSERT(mBackgroundEventTarget);
}
NS_IMETHOD
Run() override {
if (NS_IsMainThread()) {
if (!mozilla::Preferences::GetBool("dom.filesystem.pathcheck.disabled" ,
false )) {
RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
if (NS_WARN_IF(!fss || !fss->ContentProcessHasAccessTo(
mContentHandle->ChildID(), mPath))) {
AssertIsOnMainThread();
if (RefPtr<ContentParent> contentParent =
mContentHandle->GetContentParent()) {
contentParent->KillHard("This path is not allowed." );
}
return NS_OK;
}
}
return mBackgroundEventTarget->Dispatch(this , NS_DISPATCH_NORMAL);
}
AssertIsOnBackgroundThread();
// It can happen that this actor has been destroyed in the meantime we were
// on the main-thread.
if (!mActor->Destroyed()) {
mTask->Start();
}
return NS_OK;
}
private :
~CheckPermissionRunnable() {
NS_ProxyRelease("CheckPermissionRunnable::mActor" , mBackgroundEventTarget,
mActor.forget());
}
RefPtr<ThreadsafeContentParentHandle> mContentHandle;
RefPtr<FileSystemRequestParent> mActor;
RefPtr<FileSystemTaskParentBase> mTask;
const nsString mPath;
nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
};
} // namespace
void FileSystemRequestParent::Start() {
AssertIsInMainProcess();
AssertIsOnBackgroundThread();
MOZ_ASSERT(!mDestroyed);
MOZ_ASSERT(mFileSystem);
MOZ_ASSERT(mTask);
nsAutoString path;
if (NS_WARN_IF(NS_FAILED(mTask->GetTargetPath(path)))) {
(void )Send__delete__(this ,
FileSystemErrorResponse(NS_ERROR_DOM_SECURITY_ERR));
return ;
}
RefPtr<ThreadsafeContentParentHandle> parent =
BackgroundParent::GetContentParentHandle(Manager());
// If the ThreadsafeContentParentHandle is null we are dealing with a
// same-process actor.
if (!parent) {
mTask->Start();
return ;
}
RefPtr<Runnable> runnable =
new CheckPermissionRunnable(parent.forget(), this , mTask, path);
NS_DispatchToMainThread(runnable);
}
void FileSystemRequestParent::ActorDestroy(ActorDestroyReason aWhy) {
AssertIsOnBackgroundThread();
MOZ_ASSERT(!mDestroyed);
if (!mFileSystem) {
return ;
}
mFileSystem->Shutdown();
mFileSystem = nullptr;
mTask = nullptr;
mDestroyed = true ;
}
} // namespace mozilla::dom
quality 100%
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland