Bug 1258221 - patch 1 - File::CreateFromFile only for main-thread, r=smaug

This commit is contained in:
Andrea Marchesini
2016-04-09 19:15:50 +01:00
parent c505892d92
commit 8b45de854a
16 changed files with 160 additions and 215 deletions

View File

@@ -183,13 +183,14 @@ FileSystemResponseValue
CreateFileTask::GetSuccessRequestResult(ErrorResult& aRv) const CreateFileTask::GetSuccessRequestResult(ErrorResult& aRv) const
{ {
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
BlobParent* actor = GetBlobParent(mTargetBlobImpl);
if (!actor) { nsAutoString path;
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR); aRv = mTargetPath->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) {
return FileSystemDirectoryResponse();
} }
FileSystemFileResponse response;
response.blobParent() = actor; return FileSystemFileResponse(path);
return response;
} }
void void
@@ -198,8 +199,12 @@ CreateFileTask::SetSuccessRequestResult(const FileSystemResponseValue& aValue,
{ {
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
FileSystemFileResponse r = aValue; FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
mTargetBlobImpl = actor->GetBlobImpl(); NS_ConvertUTF16toUTF8 path(r.realPath());
aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(mTargetPath));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} }
nsresult nsresult
@@ -312,7 +317,6 @@ CreateFileTask::Work()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
mTargetBlobImpl = new BlobImplFile(mTargetPath);
return NS_OK; return NS_OK;
} }
@@ -331,7 +335,6 @@ CreateFileTask::Work()
return NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR; return NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR;
} }
mTargetBlobImpl = new BlobImplFile(mTargetPath);
return NS_OK; return NS_OK;
} }
@@ -352,9 +355,9 @@ CreateFileTask::HandlerCallback()
return; return;
} }
RefPtr<Blob> blob = Blob::Create(mFileSystem->GetParentObject(), RefPtr<File> file = File::CreateFromFile(mFileSystem->GetParentObject(),
mTargetBlobImpl); mTargetPath);
mPromise->MaybeResolve(blob); mPromise->MaybeResolve(file);
mPromise = nullptr; mPromise = nullptr;
mBlobData = nullptr; mBlobData = nullptr;
} }

View File

@@ -86,10 +86,6 @@ private:
nsCOMPtr<nsIInputStream> mBlobStream; nsCOMPtr<nsIInputStream> mBlobStream;
InfallibleTArray<uint8_t> mArrayData; InfallibleTArray<uint8_t> mArrayData;
bool mReplace; bool mReplace;
// This cannot be a File because this object is created on a different
// thread and File is not thread-safe. Let's use the BlobImpl instead.
RefPtr<BlobImpl> mTargetBlobImpl;
}; };
} // namespace dom } // namespace dom

View File

@@ -146,6 +146,13 @@ Directory::Create(nsISupports* aParent, nsIFile* aFile,
bool isDir; bool isDir;
nsresult rv = aFile->IsDirectory(&isDir); nsresult rv = aFile->IsDirectory(&isDir);
MOZ_ASSERT(NS_SUCCEEDED(rv) && isDir); MOZ_ASSERT(NS_SUCCEEDED(rv) && isDir);
if (aType == eNotDOMRootDirectory) {
RefPtr<nsIFile> parent;
rv = aFile->GetParent(getter_AddRefs(parent));
// We must have a parent if this is not the root directory.
MOZ_ASSERT(NS_SUCCEEDED(rv) && parent);
}
#endif #endif
RefPtr<Directory> directory = RefPtr<Directory> directory =
@@ -319,7 +326,6 @@ Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
{ {
nsresult error = NS_OK; nsresult error = NS_OK;
nsCOMPtr<nsIFile> realPath; nsCOMPtr<nsIFile> realPath;
RefPtr<BlobImpl> blob;
// Check and get the target path. // Check and get the target path.
@@ -328,25 +334,38 @@ Directory::RemoveInternal(const StringOrFileOrDirectory& aPath, bool aRecursive,
return nullptr; return nullptr;
} }
// If this is a File
if (aPath.IsFile()) { if (aPath.IsFile()) {
blob = aPath.GetAsFile().Impl(); if (!fs->GetRealPath(aPath.GetAsFile().Impl(),
getter_AddRefs(realPath))) {
error = NS_ERROR_DOM_SECURITY_ERR;
}
// If this is a string
} else if (aPath.IsString()) { } else if (aPath.IsString()) {
error = DOMPathToRealPath(aPath.GetAsString(), getter_AddRefs(realPath)); error = DOMPathToRealPath(aPath.GetAsString(), getter_AddRefs(realPath));
} else if (!fs->IsSafeDirectory(&aPath.GetAsDirectory())) {
// Directory
} else {
MOZ_ASSERT(aPath.IsDirectory());
if (!fs->IsSafeDirectory(&aPath.GetAsDirectory())) {
error = NS_ERROR_DOM_SECURITY_ERR; error = NS_ERROR_DOM_SECURITY_ERR;
} else { } else {
realPath = aPath.GetAsDirectory().mFile; realPath = aPath.GetAsDirectory().mFile;
}
}
// The target must be a descendant of this directory. // The target must be a descendant of this directory.
if (!FileSystemUtils::IsDescendantPath(mFile, realPath)) { if (!FileSystemUtils::IsDescendantPath(mFile, realPath)) {
error = NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR; error = NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR;
} }
}
RefPtr<RemoveTask> task = RefPtr<RemoveTask> task =
RemoveTask::Create(fs, mFile, blob, realPath, aRecursive, aRv); RemoveTask::Create(fs, mFile, realPath, aRecursive, aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
} }
task->SetError(error); task->SetError(error);
FileSystemPermissionRequest::RequestForTask(task); FileSystemPermissionRequest::RequestForTask(task);
return task->GetPromise(); return task->GetPromise();

View File

@@ -40,13 +40,12 @@ class Directory final
, public nsWrapperCache , public nsWrapperCache
{ {
public: public:
struct BlobImplOrDirectoryPath struct FileOrDirectoryPath
{ {
RefPtr<BlobImpl> mBlobImpl; nsString mPath;
nsString mDirectoryPath;
enum { enum {
eBlobImpl, eFilePath,
eDirectoryPath eDirectoryPath
} mType; } mType;
}; };

View File

@@ -67,9 +67,8 @@ FileSystemBase::GetParentObject() const
bool bool
FileSystemBase::GetRealPath(BlobImpl* aFile, nsIFile** aPath) const FileSystemBase::GetRealPath(BlobImpl* aFile, nsIFile** aPath) const
{ {
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
MOZ_ASSERT(aFile, "aFile Should not be null."); MOZ_ASSERT(aFile, "aFile Should not be null.");
MOZ_ASSERT(aPath);
nsAutoString filePath; nsAutoString filePath;
ErrorResult rv; ErrorResult rv;

View File

@@ -201,36 +201,6 @@ FileSystemTaskBase::Recv__delete__(const FileSystemResponseValue& aValue)
return true; return true;
} }
BlobParent*
FileSystemTaskBase::GetBlobParent(BlobImpl* aFile) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Only call from parent process!");
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(aFile);
// Load the lazy dom file data from the parent before sending to the child.
nsString mimeType;
aFile->GetType(mimeType);
// We call GetSize and GetLastModified to prepopulate the value in the
// BlobImpl.
{
ErrorResult rv;
aFile->GetSize(rv);
rv.SuppressException();
}
{
ErrorResult rv;
aFile->GetLastModified(rv);
rv.SuppressException();
}
ContentParent* cp = static_cast<ContentParent*>(mRequestParent->Manager());
return cp->GetOrCreateActorForBlobImpl(aFile);
}
void void
FileSystemTaskBase::SetError(const nsresult& aErrorValue) FileSystemTaskBase::SetError(const nsresult& aErrorValue)
{ {

View File

@@ -205,9 +205,6 @@ protected:
virtual bool virtual bool
Recv__delete__(const FileSystemResponseValue& value) override; Recv__delete__(const FileSystemResponseValue& value) override;
BlobParent*
GetBlobParent(BlobImpl* aBlob) const;
nsresult mErrorValue; nsresult mErrorValue;
RefPtr<FileSystemBase> mFileSystem; RefPtr<FileSystemBase> mFileSystem;

View File

@@ -138,19 +138,14 @@ GetDirectoryListingTask::GetSuccessRequestResult(ErrorResult& aRv) const
nsTArray<FileSystemDirectoryListingResponseData> inputs; nsTArray<FileSystemDirectoryListingResponseData> inputs;
for (unsigned i = 0; i < mTargetData.Length(); i++) { for (unsigned i = 0; i < mTargetData.Length(); i++) {
if (mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eBlobImpl) { if (mTargetData[i].mType == Directory::FileOrDirectoryPath::eFilePath) {
BlobParent* blobParent = GetBlobParent(mTargetData[i].mBlobImpl); FileSystemDirectoryListingResponseFile fileData;
if (!blobParent) { fileData.fileRealPath() = mTargetData[i].mPath;
continue; inputs.AppendElement(fileData);
}
FileSystemDirectoryListingResponseBlob blobData;
blobData.blobParent() = blobParent;
inputs.AppendElement(blobData);
} else { } else {
MOZ_ASSERT(mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eDirectoryPath); MOZ_ASSERT(mTargetData[i].mType == Directory::FileOrDirectoryPath::eDirectoryPath);
FileSystemDirectoryListingResponseDirectory directoryData; FileSystemDirectoryListingResponseDirectory directoryData;
directoryData.directoryRealPath() = mTargetData[i].mDirectoryPath; directoryData.directoryRealPath() = mTargetData[i].mPath;
inputs.AppendElement(directoryData); inputs.AppendElement(directoryData);
} }
} }
@@ -172,18 +167,16 @@ GetDirectoryListingTask::SetSuccessRequestResult(const FileSystemResponseValue&
for (uint32_t i = 0; i < r.data().Length(); ++i) { for (uint32_t i = 0; i < r.data().Length(); ++i) {
const FileSystemDirectoryListingResponseData& data = r.data()[i]; const FileSystemDirectoryListingResponseData& data = r.data()[i];
Directory::BlobImplOrDirectoryPath element; Directory::FileOrDirectoryPath element;
if (data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseBlob) { if (data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseFile) {
PBlobChild* blob = data.get_FileSystemDirectoryListingResponseBlob().blobChild(); element.mType = Directory::FileOrDirectoryPath::eFilePath;
element.mPath = data.get_FileSystemDirectoryListingResponseFile().fileRealPath();
element.mType = Directory::BlobImplOrDirectoryPath::eBlobImpl;
element.mBlobImpl = static_cast<BlobChild*>(blob)->GetBlobImpl();
} else { } else {
MOZ_ASSERT(data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseDirectory); MOZ_ASSERT(data.type() == FileSystemDirectoryListingResponseData::TFileSystemDirectoryListingResponseDirectory);
element.mType = Directory::BlobImplOrDirectoryPath::eDirectoryPath; element.mType = Directory::FileOrDirectoryPath::eDirectoryPath;
element.mDirectoryPath = data.get_FileSystemDirectoryListingResponseDirectory().directoryRealPath(); element.mPath = data.get_FileSystemDirectoryListingResponseDirectory().directoryRealPath();
} }
if (!mTargetData.AppendElement(element, fallible)) { if (!mTargetData.AppendElement(element, fallible)) {
@@ -292,21 +285,15 @@ GetDirectoryListingTask::Work()
} }
} }
Directory::BlobImplOrDirectoryPath element;
if (isDir) {
nsAutoString path; nsAutoString path;
if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) { if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) {
continue; continue;
} }
element.mType = Directory::BlobImplOrDirectoryPath::eDirectoryPath; Directory::FileOrDirectoryPath element;
element.mDirectoryPath = path; element.mPath = path;
} else { element.mType = isDir ? Directory::FileOrDirectoryPath::eDirectoryPath
BlobImplFile* impl = new BlobImplFile(currFile); : Directory::FileOrDirectoryPath::eFilePath;
element.mType = Directory::BlobImplOrDirectoryPath::eBlobImpl;
element.mBlobImpl = impl;
}
if (!mTargetData.AppendElement(element, fallible)) { if (!mTargetData.AppendElement(element, fallible)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
@@ -341,11 +328,9 @@ GetDirectoryListingTask::HandlerCallback()
} }
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
if (mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eDirectoryPath) { nsCOMPtr<nsIFile> path;
nsCOMPtr<nsIFile> directoryPath; NS_ConvertUTF16toUTF8 fullPath(mTargetData[i].mPath);
NS_ConvertUTF16toUTF8 path(mTargetData[i].mDirectoryPath); nsresult rv = NS_NewNativeLocalFile(fullPath, true, getter_AddRefs(path));
nsresult rv = NS_NewNativeLocalFile(path, true,
getter_AddRefs(directoryPath));
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
mPromise->MaybeReject(rv); mPromise->MaybeReject(rv);
mPromise = nullptr; mPromise = nullptr;
@@ -362,23 +347,26 @@ GetDirectoryListingTask::HandlerCallback()
return; return;
} }
MOZ_ASSERT(FileSystemUtils::IsDescendantPath(rootPath, directoryPath)); MOZ_ASSERT(FileSystemUtils::IsDescendantPath(rootPath, path));
#endif #endif
if (mTargetData[i].mType == Directory::FileOrDirectoryPath::eDirectoryPath) {
RefPtr<Directory> directory = RefPtr<Directory> directory =
Directory::Create(mFileSystem->GetParentObject(), Directory::Create(mFileSystem->GetParentObject(), path,
directoryPath, Directory::eNotDOMRootDirectory, mFileSystem);
Directory::eNotDOMRootDirectory,
mFileSystem);
MOZ_ASSERT(directory); MOZ_ASSERT(directory);
// Propogate mFilter onto sub-Directory object: // Propogate mFilter onto sub-Directory object:
directory->SetContentFilters(mFilters); directory->SetContentFilters(mFilters);
listing[i].SetAsDirectory() = directory; listing[i].SetAsDirectory() = directory;
} else { } else {
MOZ_ASSERT(mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eBlobImpl); MOZ_ASSERT(mTargetData[i].mType == Directory::FileOrDirectoryPath::eFilePath);
listing[i].SetAsFile() =
File::Create(mFileSystem->GetParentObject(), mTargetData[i].mBlobImpl); RefPtr<File> file =
File::CreateFromFile(mFileSystem->GetParentObject(), path);
MOZ_ASSERT(file);
listing[i].SetAsFile() = file;
} }
} }

View File

@@ -77,7 +77,7 @@ private:
// We cannot store File or Directory objects bacause this object is created // We cannot store File or Directory objects bacause this object is created
// on a different thread and File and Directory are not thread-safe. // on a different thread and File and Directory are not thread-safe.
FallibleTArray<Directory::BlobImplOrDirectoryPath> mTargetData; FallibleTArray<Directory::FileOrDirectoryPath> mTargetData;
}; };
} // namespace dom } // namespace dom

View File

@@ -130,23 +130,17 @@ FileSystemResponseValue
GetFileOrDirectoryTask::GetSuccessRequestResult(ErrorResult& aRv) const GetFileOrDirectoryTask::GetSuccessRequestResult(ErrorResult& aRv) const
{ {
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
if (mIsDirectory) {
nsAutoString path; nsAutoString path;
aRv = mTargetPath->GetPath(path); aRv = mTargetPath->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return FileSystemDirectoryResponse(); return FileSystemDirectoryResponse();
} }
if (mIsDirectory) {
return FileSystemDirectoryResponse(path); return FileSystemDirectoryResponse(path);
} }
BlobParent* actor = GetBlobParent(mTargetBlobImpl); return FileSystemFileResponse(path);
if (!actor) {
return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR);
}
FileSystemFileResponse response;
response.blobParent() = actor;
return response;
} }
void void
@@ -157,8 +151,13 @@ GetFileOrDirectoryTask::SetSuccessRequestResult(const FileSystemResponseValue& a
switch (aValue.type()) { switch (aValue.type()) {
case FileSystemResponseValue::TFileSystemFileResponse: { case FileSystemResponseValue::TFileSystemFileResponse: {
FileSystemFileResponse r = aValue; FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
mTargetBlobImpl = actor->GetBlobImpl(); NS_ConvertUTF16toUTF8 path(r.realPath());
aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(mTargetPath));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
mIsDirectory = false; mIsDirectory = false;
break; break;
} }
@@ -242,8 +241,6 @@ GetFileOrDirectoryTask::Work()
return NS_ERROR_DOM_SECURITY_ERR; return NS_ERROR_DOM_SECURITY_ERR;
} }
mTargetBlobImpl = new BlobImplFile(mTargetPath);
return NS_OK; return NS_OK;
} }
@@ -274,9 +271,9 @@ GetFileOrDirectoryTask::HandlerCallback()
return; return;
} }
RefPtr<Blob> blob = Blob::Create(mFileSystem->GetParentObject(), RefPtr<File> file = File::CreateFromFile(mFileSystem->GetParentObject(),
mTargetBlobImpl); mTargetPath);
mPromise->MaybeResolve(blob); mPromise->MaybeResolve(file);
mPromise = nullptr; mPromise = nullptr;
} }

View File

@@ -76,10 +76,6 @@ private:
// Whether we get a directory. // Whether we get a directory.
bool mIsDirectory; bool mIsDirectory;
Directory::DirectoryType mType; Directory::DirectoryType mType;
// This cannot be a File bacause this object is created on a different
// thread and File is not thread-safe. Let's use the BlobImpl instead.
RefPtr<BlobImpl> mTargetBlobImpl;
}; };
} // namespace dom } // namespace dom

View File

@@ -12,7 +12,7 @@ namespace dom {
struct FileSystemFileResponse struct FileSystemFileResponse
{ {
PBlob blob; nsString realPath;
}; };
struct FileSystemDirectoryResponse struct FileSystemDirectoryResponse
@@ -20,9 +20,10 @@ struct FileSystemDirectoryResponse
nsString realPath; nsString realPath;
}; };
struct FileSystemDirectoryListingResponseBlob struct FileSystemDirectoryListingResponseFile
{ {
PBlob blob; // This is the full real path for the file that we are sending via IPC.
nsString fileRealPath;
}; };
struct FileSystemDirectoryListingResponseDirectory struct FileSystemDirectoryListingResponseDirectory
@@ -33,7 +34,7 @@ struct FileSystemDirectoryListingResponseDirectory
union FileSystemDirectoryListingResponseData union FileSystemDirectoryListingResponseData
{ {
FileSystemDirectoryListingResponseBlob; FileSystemDirectoryListingResponseFile;
FileSystemDirectoryListingResponseDirectory; FileSystemDirectoryListingResponseDirectory;
}; };

View File

@@ -21,7 +21,6 @@ namespace dom {
/* static */ already_AddRefed<RemoveTask> /* static */ already_AddRefed<RemoveTask>
RemoveTask::Create(FileSystemBase* aFileSystem, RemoveTask::Create(FileSystemBase* aFileSystem,
nsIFile* aDirPath, nsIFile* aDirPath,
BlobImpl* aTargetBlob,
nsIFile* aTargetPath, nsIFile* aTargetPath,
bool aRecursive, bool aRecursive,
ErrorResult& aRv) ErrorResult& aRv)
@@ -29,9 +28,10 @@ RemoveTask::Create(FileSystemBase* aFileSystem,
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
MOZ_ASSERT(aDirPath); MOZ_ASSERT(aDirPath);
MOZ_ASSERT(aTargetPath);
RefPtr<RemoveTask> task = RefPtr<RemoveTask> task =
new RemoveTask(aFileSystem, aDirPath, aTargetBlob, aTargetPath, aRecursive); new RemoveTask(aFileSystem, aDirPath, aTargetPath, aRecursive);
// aTargetPath can be null. In this case SetError will be called. // aTargetPath can be null. In this case SetError will be called.
@@ -72,33 +72,26 @@ RemoveTask::Create(FileSystemBase* aFileSystem,
task->mRecursive = aParam.recursive(); task->mRecursive = aParam.recursive();
const FileSystemPathOrFileValue& target = aParam.target(); NS_ConvertUTF16toUTF8 path(aParam.targetDirectory());
if (target.type() == FileSystemPathOrFileValue::TnsString) {
NS_ConvertUTF16toUTF8 path(target);
aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath)); aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath));
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
} }
return task.forget(); if (!FileSystemUtils::IsDescendantPath(task->mDirPath, task->mTargetPath)) {
aRv.Throw(NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR);
return nullptr;
} }
BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(target));
task->mTargetBlobImpl = bp->GetBlobImpl();
MOZ_ASSERT(task->mTargetBlobImpl);
return task.forget(); return task.forget();
} }
RemoveTask::RemoveTask(FileSystemBase* aFileSystem, RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
nsIFile* aDirPath, nsIFile* aDirPath,
BlobImpl* aTargetBlob,
nsIFile* aTargetPath, nsIFile* aTargetPath,
bool aRecursive) bool aRecursive)
: FileSystemTaskBase(aFileSystem) : FileSystemTaskBase(aFileSystem)
, mDirPath(aDirPath) , mDirPath(aDirPath)
, mTargetBlobImpl(aTargetBlob)
, mTargetPath(aTargetPath) , mTargetPath(aTargetPath)
, mRecursive(aRecursive) , mRecursive(aRecursive)
, mReturnValue(false) , mReturnValue(false)
@@ -106,6 +99,7 @@ RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
MOZ_ASSERT(aFileSystem); MOZ_ASSERT(aFileSystem);
MOZ_ASSERT(aDirPath); MOZ_ASSERT(aDirPath);
MOZ_ASSERT(aTargetPath);
} }
RemoveTask::RemoveTask(FileSystemBase* aFileSystem, RemoveTask::RemoveTask(FileSystemBase* aFileSystem,
@@ -147,23 +141,15 @@ RemoveTask::GetRequestParams(const nsString& aSerializedDOMPath,
} }
param.recursive() = mRecursive; param.recursive() = mRecursive;
if (mTargetBlobImpl) {
RefPtr<Blob> blob = Blob::Create(mFileSystem->GetParentObject(),
mTargetBlobImpl);
BlobChild* actor
= ContentChild::GetSingleton()->GetOrCreateActorForBlob(blob);
if (actor) {
param.target() = actor;
}
} else {
nsAutoString path; nsAutoString path;
aRv = mTargetPath->GetPath(path); aRv = mTargetPath->GetPath(path);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return param; return param;
} }
param.target() = path; param.targetDirectory() = path;
}
return param; return param;
} }
@@ -194,16 +180,7 @@ RemoveTask::Work()
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Get the path if a File is passed as the target. MOZ_ASSERT(FileSystemUtils::IsDescendantPath(mDirPath, mTargetPath));
if (mTargetBlobImpl) {
if (!mFileSystem->GetRealPath(mTargetBlobImpl,
getter_AddRefs(mTargetPath))) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!FileSystemUtils::IsDescendantPath(mDirPath, mTargetPath)) {
return NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR;
}
}
bool exists = false; bool exists = false;
nsresult rv = mTargetPath->Exists(&exists); nsresult rv = mTargetPath->Exists(&exists);

View File

@@ -23,7 +23,6 @@ public:
static already_AddRefed<RemoveTask> static already_AddRefed<RemoveTask>
Create(FileSystemBase* aFileSystem, Create(FileSystemBase* aFileSystem,
nsIFile* aDirPath, nsIFile* aDirPath,
BlobImpl* aTargetBlob,
nsIFile* aTargetPath, nsIFile* aTargetPath,
bool aRecursive, bool aRecursive,
ErrorResult& aRv); ErrorResult& aRv);
@@ -64,7 +63,6 @@ protected:
private: private:
RemoveTask(FileSystemBase* aFileSystem, RemoveTask(FileSystemBase* aFileSystem,
nsIFile* aDirPath, nsIFile* aDirPath,
BlobImpl* aTargetBlob,
nsIFile* aTargetPath, nsIFile* aTargetPath,
bool aRecursive); bool aRecursive);
@@ -73,12 +71,13 @@ private:
FileSystemRequestParent* aParent); FileSystemRequestParent* aParent);
RefPtr<Promise> mPromise; RefPtr<Promise> mPromise;
// This path is the Directory::mFile.
nsCOMPtr<nsIFile> mDirPath; nsCOMPtr<nsIFile> mDirPath;
// This cannot be a File because this object will be used on a different // This is what we want to remove. mTargetPath is discendant path of mDirPath.
// thread and File is not thread-safe. Let's use the BlobImpl instead.
RefPtr<BlobImpl> mTargetBlobImpl;
nsCOMPtr<nsIFile> mTargetPath; nsCOMPtr<nsIFile> mTargetPath;
bool mRecursive; bool mRecursive;
bool mReturnValue; bool mReturnValue;
}; };

View File

@@ -254,7 +254,7 @@ class HTMLInputElementState final : public nsISupports
nsTArray<OwningFileOrDirectory>& aResult) const nsTArray<OwningFileOrDirectory>& aResult) const
{ {
for (uint32_t i = 0; i < mBlobImplsOrDirectoryPaths.Length(); ++i) { for (uint32_t i = 0; i < mBlobImplsOrDirectoryPaths.Length(); ++i) {
if (mBlobImplsOrDirectoryPaths[i].mType == Directory::BlobImplOrDirectoryPath::eBlobImpl) { if (mBlobImplsOrDirectoryPaths[i].mType == BlobImplOrDirectoryPath::eBlobImpl) {
RefPtr<File> file = RefPtr<File> file =
File::Create(aWindow, File::Create(aWindow,
mBlobImplsOrDirectoryPaths[i].mBlobImpl); mBlobImplsOrDirectoryPaths[i].mBlobImpl);
@@ -263,7 +263,7 @@ class HTMLInputElementState final : public nsISupports
OwningFileOrDirectory* element = aResult.AppendElement(); OwningFileOrDirectory* element = aResult.AppendElement();
element->SetAsFile() = file; element->SetAsFile() = file;
} else { } else {
MOZ_ASSERT(mBlobImplsOrDirectoryPaths[i].mType == Directory::BlobImplOrDirectoryPath::eDirectoryPath); MOZ_ASSERT(mBlobImplsOrDirectoryPaths[i].mType == BlobImplOrDirectoryPath::eDirectoryPath);
nsCOMPtr<nsIFile> file; nsCOMPtr<nsIFile> file;
NS_ConvertUTF16toUTF8 path(mBlobImplsOrDirectoryPaths[i].mDirectoryPath); NS_ConvertUTF16toUTF8 path(mBlobImplsOrDirectoryPaths[i].mDirectoryPath);
@@ -287,11 +287,10 @@ class HTMLInputElementState final : public nsISupports
mBlobImplsOrDirectoryPaths.Clear(); mBlobImplsOrDirectoryPaths.Clear();
for (uint32_t i = 0; i < aArray.Length(); ++i) { for (uint32_t i = 0; i < aArray.Length(); ++i) {
if (aArray[i].IsFile()) { if (aArray[i].IsFile()) {
Directory::BlobImplOrDirectoryPath* data = BlobImplOrDirectoryPath* data = mBlobImplsOrDirectoryPaths.AppendElement();
mBlobImplsOrDirectoryPaths.AppendElement();
data->mBlobImpl = aArray[i].GetAsFile()->Impl(); data->mBlobImpl = aArray[i].GetAsFile()->Impl();
data->mType = Directory::BlobImplOrDirectoryPath::eBlobImpl; data->mType = BlobImplOrDirectoryPath::eBlobImpl;
} else { } else {
MOZ_ASSERT(aArray[i].IsDirectory()); MOZ_ASSERT(aArray[i].IsDirectory());
nsAutoString fullPath; nsAutoString fullPath;
@@ -300,11 +299,11 @@ class HTMLInputElementState final : public nsISupports
continue; continue;
} }
Directory::BlobImplOrDirectoryPath* data = BlobImplOrDirectoryPath* data =
mBlobImplsOrDirectoryPaths.AppendElement(); mBlobImplsOrDirectoryPaths.AppendElement();
data->mDirectoryPath = fullPath; data->mDirectoryPath = fullPath;
data->mType = Directory::BlobImplOrDirectoryPath::eDirectoryPath; data->mType = BlobImplOrDirectoryPath::eDirectoryPath;
} }
} }
} }
@@ -320,7 +319,18 @@ class HTMLInputElementState final : public nsISupports
nsString mValue; nsString mValue;
nsTArray<Directory::BlobImplOrDirectoryPath> mBlobImplsOrDirectoryPaths; struct BlobImplOrDirectoryPath
{
RefPtr<BlobImpl> mBlobImpl;
nsString mDirectoryPath;
enum {
eBlobImpl,
eDirectoryPath
} mType;
};
nsTArray<BlobImplOrDirectoryPath> mBlobImplsOrDirectoryPaths;
bool mChecked; bool mChecked;
bool mCheckedSet; bool mCheckedSet;

View File

@@ -311,17 +311,11 @@ struct FileSystemGetFileOrDirectoryParams
bool isRoot; bool isRoot;
}; };
union FileSystemPathOrFileValue
{
nsString;
PBlob;
};
struct FileSystemRemoveParams struct FileSystemRemoveParams
{ {
nsString filesystem; nsString filesystem;
nsString directory; nsString directory;
FileSystemPathOrFileValue target; nsString targetDirectory;
bool recursive; bool recursive;
}; };