Bug 1258221 - patch 1 - File::CreateFromFile only for main-thread, r=smaug
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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())) {
|
|
||||||
error = NS_ERROR_DOM_SECURITY_ERR;
|
// Directory
|
||||||
} else {
|
} else {
|
||||||
realPath = aPath.GetAsDirectory().mFile;
|
MOZ_ASSERT(aPath.IsDirectory());
|
||||||
// The target must be a descendant of this directory.
|
if (!fs->IsSafeDirectory(&aPath.GetAsDirectory())) {
|
||||||
if (!FileSystemUtils::IsDescendantPath(mFile, realPath)) {
|
error = NS_ERROR_DOM_SECURITY_ERR;
|
||||||
error = NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR;
|
} else {
|
||||||
|
realPath = aPath.GetAsDirectory().mFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The target must be a descendant of this directory.
|
||||||
|
if (!FileSystemUtils::IsDescendantPath(mFile, realPath)) {
|
||||||
|
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();
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,22 +285,16 @@ GetDirectoryListingTask::Work()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Directory::BlobImplOrDirectoryPath element;
|
nsAutoString path;
|
||||||
if (isDir) {
|
if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) {
|
||||||
nsAutoString path;
|
continue;
|
||||||
if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
element.mType = Directory::BlobImplOrDirectoryPath::eDirectoryPath;
|
|
||||||
element.mDirectoryPath = path;
|
|
||||||
} else {
|
|
||||||
BlobImplFile* impl = new BlobImplFile(currFile);
|
|
||||||
|
|
||||||
element.mType = Directory::BlobImplOrDirectoryPath::eBlobImpl;
|
|
||||||
element.mBlobImpl = impl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Directory::FileOrDirectoryPath element;
|
||||||
|
element.mPath = path;
|
||||||
|
element.mType = isDir ? Directory::FileOrDirectoryPath::eDirectoryPath
|
||||||
|
: Directory::FileOrDirectoryPath::eFilePath;
|
||||||
|
|
||||||
if (!mTargetData.AppendElement(element, fallible)) {
|
if (!mTargetData.AppendElement(element, fallible)) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -341,44 +328,45 @@ 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,
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
getter_AddRefs(directoryPath));
|
mPromise->MaybeReject(rv);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
mPromise = nullptr;
|
||||||
mPromise->MaybeReject(rv);
|
return;
|
||||||
mPromise = nullptr;
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
nsCOMPtr<nsIFile> rootPath;
|
nsCOMPtr<nsIFile> rootPath;
|
||||||
rv = NS_NewLocalFile(mFileSystem->LocalOrDeviceStorageRootPath(), false,
|
rv = NS_NewLocalFile(mFileSystem->LocalOrDeviceStorageRootPath(), false,
|
||||||
getter_AddRefs(rootPath));
|
getter_AddRefs(rootPath));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
mPromise->MaybeReject(rv);
|
mPromise->MaybeReject(rv);
|
||||||
mPromise = nullptr;
|
mPromise = nullptr;
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath));
|
||||||
if (target.type() == FileSystemPathOrFileValue::TnsString) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
NS_ConvertUTF16toUTF8 path(target);
|
return nullptr;
|
||||||
aRv = NS_NewNativeLocalFile(path, true, getter_AddRefs(task->mTargetPath));
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return task.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobParent* bp = static_cast<BlobParent*>(static_cast<PBlobParent*>(target));
|
if (!FileSystemUtils::IsDescendantPath(task->mDirPath, task->mTargetPath)) {
|
||||||
task->mTargetBlobImpl = bp->GetBlobImpl();
|
aRv.Throw(NS_ERROR_DOM_FILESYSTEM_NO_MODIFICATION_ALLOWED_ERR);
|
||||||
MOZ_ASSERT(task->mTargetBlobImpl);
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
aRv = mTargetPath->GetPath(path);
|
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
|
|
||||||
param.target() = path;
|
nsAutoString path;
|
||||||
|
aRv = mTargetPath->GetPath(path);
|
||||||
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user