Bug 1850713: remove duplicated setting of early hint preloader id in `ScriptLoader...
[gecko.git] / dom / filesystem / FileSystemRequestParent.cpp
blob25211dbd23e46fe0eb2d8bdf07285c1dce2920d9
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/FileSystemRequestParent.h"
8 #include "mozilla/dom/PFileSystemParams.h"
10 #include "GetDirectoryListingTask.h"
11 #include "GetFileOrDirectoryTask.h"
12 #include "GetFilesTask.h"
14 #include "mozilla/dom/BlobImpl.h"
15 #include "mozilla/dom/ContentParent.h"
16 #include "mozilla/dom/FileSystemBase.h"
17 #include "mozilla/dom/FileSystemSecurity.h"
18 #include "mozilla/ipc/BackgroundParent.h"
19 #include "mozilla/dom/OSFileSystem.h"
20 #include "mozilla/Preferences.h"
21 #include "mozilla/ScopeExit.h"
22 #include "mozilla/Unused.h"
23 #include "nsProxyRelease.h"
25 using namespace mozilla::ipc;
27 namespace mozilla::dom {
29 FileSystemRequestParent::FileSystemRequestParent() : mDestroyed(false) {
30 AssertIsOnBackgroundThread();
33 FileSystemRequestParent::~FileSystemRequestParent() {
34 AssertIsOnBackgroundThread();
37 #define FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(name) \
38 case FileSystemParams::TFileSystem##name##Params: { \
39 const FileSystem##name##Params& p = aParams; \
40 mFileSystem = new OSFileSystemParent(p.filesystem()); \
41 MOZ_ASSERT(mFileSystem); \
42 mTask = name##TaskParent::Create(mFileSystem, p, this, rv); \
43 if (NS_WARN_IF(rv.Failed())) { \
44 rv.SuppressException(); \
45 return false; \
46 } \
47 break; \
50 bool FileSystemRequestParent::Initialize(const FileSystemParams& aParams) {
51 AssertIsOnBackgroundThread();
53 ErrorResult rv;
55 switch (aParams.type()) {
56 FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetDirectoryListing)
57 FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetFileOrDirectory)
58 FILESYSTEM_REQUEST_PARENT_DISPATCH_ENTRY(GetFiles)
60 default: {
61 MOZ_CRASH("not reached");
62 break;
66 if (NS_WARN_IF(!mTask || !mFileSystem)) {
67 // Should never reach here.
68 return false;
71 return true;
74 namespace {
76 class CheckPermissionRunnable final : public Runnable {
77 public:
78 CheckPermissionRunnable(
79 already_AddRefed<ThreadsafeContentParentHandle> aParent,
80 FileSystemRequestParent* aActor, FileSystemTaskParentBase* aTask,
81 const nsAString& aPath)
82 : Runnable("dom::CheckPermissionRunnable"),
83 mContentHandle(aParent),
84 mActor(aActor),
85 mTask(aTask),
86 mPath(aPath),
87 mBackgroundEventTarget(GetCurrentSerialEventTarget()) {
88 AssertIsInMainProcess();
89 AssertIsOnBackgroundThread();
91 MOZ_ASSERT(mContentHandle);
92 MOZ_ASSERT(mActor);
93 MOZ_ASSERT(mTask);
94 MOZ_ASSERT(mBackgroundEventTarget);
97 NS_IMETHOD
98 Run() override {
99 if (NS_IsMainThread()) {
100 if (!mozilla::Preferences::GetBool("dom.filesystem.pathcheck.disabled",
101 false)) {
102 RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
103 if (NS_WARN_IF(!fss || !fss->ContentProcessHasAccessTo(
104 mContentHandle->ChildID(), mPath))) {
105 AssertIsOnMainThread();
106 if (RefPtr<ContentParent> contentParent =
107 mContentHandle->GetContentParent()) {
108 contentParent->KillHard("This path is not allowed.");
110 return NS_OK;
114 return mBackgroundEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
117 AssertIsOnBackgroundThread();
119 // It can happen that this actor has been destroyed in the meantime we were
120 // on the main-thread.
121 if (!mActor->Destroyed()) {
122 mTask->Start();
125 return NS_OK;
128 private:
129 ~CheckPermissionRunnable() {
130 NS_ProxyRelease("CheckPermissionRunnable::mActor", mBackgroundEventTarget,
131 mActor.forget());
134 RefPtr<ThreadsafeContentParentHandle> mContentHandle;
135 RefPtr<FileSystemRequestParent> mActor;
136 RefPtr<FileSystemTaskParentBase> mTask;
137 const nsString mPath;
139 nsCOMPtr<nsIEventTarget> mBackgroundEventTarget;
142 } // namespace
144 void FileSystemRequestParent::Start() {
145 AssertIsInMainProcess();
146 AssertIsOnBackgroundThread();
148 MOZ_ASSERT(!mDestroyed);
149 MOZ_ASSERT(mFileSystem);
150 MOZ_ASSERT(mTask);
152 nsAutoString path;
153 if (NS_WARN_IF(NS_FAILED(mTask->GetTargetPath(path)))) {
154 (void)Send__delete__(this,
155 FileSystemErrorResponse(NS_ERROR_DOM_SECURITY_ERR));
156 return;
159 RefPtr<ThreadsafeContentParentHandle> parent =
160 BackgroundParent::GetContentParentHandle(Manager());
162 // If the ThreadsafeContentParentHandle is null we are dealing with a
163 // same-process actor.
164 if (!parent) {
165 mTask->Start();
166 return;
169 RefPtr<Runnable> runnable =
170 new CheckPermissionRunnable(parent.forget(), this, mTask, path);
171 NS_DispatchToMainThread(runnable);
174 void FileSystemRequestParent::ActorDestroy(ActorDestroyReason aWhy) {
175 AssertIsOnBackgroundThread();
176 MOZ_ASSERT(!mDestroyed);
178 if (!mFileSystem) {
179 return;
182 mFileSystem->Shutdown();
183 mFileSystem = nullptr;
184 mTask = nullptr;
185 mDestroyed = true;
188 } // namespace mozilla::dom