--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -96,18 +96,19 @@ public:
NS_DECL_THREADSAFE_ISUPPORTS
bool IsAvailable();
void GetFullPath(nsAString& aFullPath);
// we want to make sure that the names of file can't reach
// outside of the type of storage the user asked for.
- bool IsSafePath();
- bool IsSafePath(const nsAString& aPath);
+ bool IsSafePath() const;
+ bool ValidateAndSplitPath(const nsAString& aPath,
+ nsTArray<nsString>* aParts = nullptr) const;
void Dump(const char* label);
nsresult Remove();
nsresult Write(nsIInputStream* aInputStream);
nsresult Write(InfallibleTArray<uint8_t>& bits);
nsresult Append(nsIInputStream* aInputStream);
nsresult Append(nsIInputStream* aInputStream,
@@ -132,17 +133,16 @@ public:
nsresult CalculateSizeAndModifiedDate();
nsresult CalculateMimeType();
nsresult CreateFileDescriptor(mozilla::ipc::FileDescriptor& aFileDescriptor);
private:
~DeviceStorageFile() {}
void Init();
- void NormalizeFilePath();
void AppendRelativePath(const nsAString& aPath);
void AccumDirectoryUsage(nsIFile* aFile,
uint64_t* aPicturesSoFar,
uint64_t* aVideosSoFar,
uint64_t* aMusicSoFar,
uint64_t* aTotalSoFar);
};
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -25,16 +25,17 @@
#include "mozilla/EventListenerManager.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Scoped.h"
#include "mozilla/Services.h"
#include "mozilla/ipc/BackgroundUtils.h" // for PrincipalInfoToPrincipal
#include "nsArrayUtils.h"
#include "nsAutoPtr.h"
+#include "nsCharSeparatedTokenizer.h"
#include "nsGlobalWindow.h"
#include "nsServiceManagerUtils.h"
#include "nsIFile.h"
#include "nsIDirectoryEnumerator.h"
#include "nsNetUtil.h"
#include "nsIOutputStream.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIPrincipal.h"
@@ -71,20 +72,45 @@
#define DEFAULT_THREAD_TIMEOUT_MS 30000
#define STORAGE_CHANGE_EVENT "change"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::devicestorage;
using namespace mozilla::ipc;
-namespace mozilla {
+namespace mozilla
+{
MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, PR_Close);
} // namespace mozilla
+namespace {
+
+void
+NormalizeFilePath(nsAString& aPath)
+{
+#if defined(XP_WIN)
+ char16_t* cur = aPath.BeginWriting();
+ char16_t* end = aPath.EndWriting();
+ for (; cur < end; ++cur) {
+ if (char16_t('\\') == *cur) {
+ *cur = FILESYSTEM_DOM_PATH_SEPARATOR_CHAR;
+ }
+ }
+#endif
+}
+
+bool
+TokenizerIgnoreNothing(char16_t /* aChar */)
+{
+ return false;
+}
+
+} // anonymous namespace
+
StaticAutoPtr<DeviceStorageUsedSpaceCache>
DeviceStorageUsedSpaceCache::sDeviceStorageUsedSpaceCache;
DeviceStorageUsedSpaceCache::DeviceStorageUsedSpaceCache()
{
MOZ_ASSERT(NS_IsMainThread());
mIOThread = new LazyIdleThread(
@@ -505,32 +531,33 @@ DeviceStorageFile::DeviceStorageFile(con
, mLength(UINT64_MAX)
, mLastModifiedDate(UINT64_MAX)
{
Init();
AppendRelativePath(mRootDir);
if (!mPath.EqualsLiteral("")) {
AppendRelativePath(mPath);
}
- NormalizeFilePath();
+
+ NormalizeFilePath(mPath);
}
DeviceStorageFile::DeviceStorageFile(const nsAString& aStorageType,
const nsAString& aStorageName,
const nsAString& aPath)
: mStorageType(aStorageType)
, mStorageName(aStorageName)
, mPath(aPath)
, mEditable(false)
, mLength(UINT64_MAX)
, mLastModifiedDate(UINT64_MAX)
{
Init();
AppendRelativePath(aPath);
- NormalizeFilePath();
+ NormalizeFilePath(mPath);
}
DeviceStorageFile::DeviceStorageFile(const nsAString& aStorageType,
const nsAString& aStorageName)
: mStorageType(aStorageType)
, mStorageName(aStorageName)
, mEditable(false)
, mLength(UINT64_MAX)
@@ -729,85 +756,100 @@ DeviceStorageFile::CreateUnique(const ns
}
return dsf.forget();
}
void
DeviceStorageFile::SetPath(const nsAString& aPath) {
mPath.Assign(aPath);
- NormalizeFilePath();
+ NormalizeFilePath(mPath);
}
void
DeviceStorageFile::SetEditable(bool aEditable) {
mEditable = aEditable;
}
// we want to make sure that the names of file can't reach
// outside of the type of storage the user asked for.
bool
-DeviceStorageFile::IsSafePath()
+DeviceStorageFile::IsSafePath() const
{
- return IsSafePath(mRootDir) && IsSafePath(mPath);
+ return ValidateAndSplitPath(mRootDir) && ValidateAndSplitPath(mPath);
}
bool
-DeviceStorageFile::IsSafePath(const nsAString& aPath)
+DeviceStorageFile::ValidateAndSplitPath(const nsAString& aPath,
+ nsTArray<nsString>* aParts) const
{
nsAString::const_iterator start, end;
aPath.BeginReading(start);
aPath.EndReading(end);
// if the path is a '~' or starts with '~/', return false.
NS_NAMED_LITERAL_STRING(tilde, "~");
NS_NAMED_LITERAL_STRING(tildeSlash, "~/");
if (aPath.Equals(tilde) ||
StringBeginsWith(aPath, tildeSlash)) {
NS_WARNING("Path name starts with tilde!");
return false;
- }
- // split on /. if any token is "", ., or .., return false.
- NS_ConvertUTF16toUTF8 cname(aPath);
- char* buffer = cname.BeginWriting();
- const char* token;
-
- while ((token = nsCRT::strtok(buffer, "/", &buffer))) {
- if (PL_strcmp(token, "") == 0 ||
- PL_strcmp(token, ".") == 0 ||
- PL_strcmp(token, "..") == 0 ) {
+ }
+
+ NS_NAMED_LITERAL_STRING(kCurrentDir, ".");
+ NS_NAMED_LITERAL_STRING(kParentDir, "..");
+
+ // Split path and check each path component.
+ nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing>
+ tokenizer(aPath, FILESYSTEM_DOM_PATH_SEPARATOR_CHAR);
+
+ while (tokenizer.hasMoreTokens()) {
+ nsDependentSubstring pathComponent = tokenizer.nextToken();
+ // The path containing empty components, such as "foo//bar", is invalid.
+ // We don't allow paths, such as "../foo", "foo/./bar" and "foo/../bar",
+ // to walk up the directory.
+ if (pathComponent.IsEmpty() ||
+ pathComponent.Equals(kCurrentDir) ||
+ pathComponent.Equals(kParentDir)) {
return false;
}
+
+ if (aParts) {
+ aParts->AppendElement(pathComponent);
+ }
}
return true;
}
void
-DeviceStorageFile::NormalizeFilePath() {
- FileSystemUtils::LocalPathToNormalizedPath(mPath, mPath);
-}
-
-void
-DeviceStorageFile::AppendRelativePath(const nsAString& aPath) {
+DeviceStorageFile::AppendRelativePath(const nsAString& aPath)
+{
if (!mFile) {
return;
}
- if (!IsSafePath(aPath)) {
+
+ nsTArray<nsString> parts;
+
+ if (!ValidateAndSplitPath(aPath, &parts)) {
// All of the APIs (in the child) do checks to verify that the path is
// valid and return PERMISSION_DENIED if a non-safe path is entered.
// This check is done in the parent and prevents a compromised
// child from bypassing the check. It shouldn't be possible for this
// code path to be taken with a non-compromised child.
NS_WARNING("Unsafe path detected - ignoring");
NS_WARNING(NS_LossyConvertUTF16toASCII(aPath).get());
return;
}
- nsString localPath;
- FileSystemUtils::NormalizedPathToLocalPath(aPath, localPath);
- mFile->AppendRelativePath(localPath);
+
+ for (uint32_t i = 0; i < parts.Length(); ++i) {
+ nsresult rv = mFile->AppendRelativePath(parts[i]);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return;
+ }
+ }
}
nsresult
DeviceStorageFile::CreateFileDescriptor(FileDescriptor& aFileDescriptor)
{
if (!mFile) {
return NS_ERROR_FAILURE;
}
--- a/dom/filesystem/CreateFileTask.cpp
+++ b/dom/filesystem/CreateFileTask.cpp
@@ -163,18 +163,18 @@ CreateFileTask::GetRequestParams(const n
aRv = mTargetPath->GetPath(param.realPath());
if (NS_WARN_IF(aRv.Failed())) {
return param;
}
param.replace() = mReplace;
if (mBlobData) {
- BlobChild* actor
- = ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlobData);
+ BlobChild* actor =
+ ContentChild::GetSingleton()->GetOrCreateActorForBlob(mBlobData);
if (actor) {
param.data() = actor;
}
} else {
param.data() = mArrayData;
}
return param;
}
@@ -200,29 +200,30 @@ CreateFileTask::SetSuccessRequestResult(
FileSystemFileResponse r = aValue;
BlobChild* actor = static_cast<BlobChild*>(r.blobChild());
mTargetBlobImpl = actor->GetBlobImpl();
}
nsresult
CreateFileTask::Work()
{
- class AutoClose
+ class MOZ_RAII AutoClose final
{
public:
explicit AutoClose(nsIOutputStream* aStream)
: mStream(aStream)
{
MOZ_ASSERT(aStream);
}
~AutoClose()
{
mStream->Close();
}
+
private:
nsCOMPtr<nsIOutputStream> mStream;
};
MOZ_ASSERT(XRE_IsParentProcess(),
"Only call from parent process!");
MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");
--- a/dom/filesystem/DeviceStorageFileSystem.cpp
+++ b/dom/filesystem/DeviceStorageFileSystem.cpp
@@ -16,19 +16,18 @@
#include "nsDeviceStorage.h"
#include "nsIFile.h"
#include "nsPIDOMWindow.h"
#include "nsGlobalWindow.h"
namespace mozilla {
namespace dom {
-DeviceStorageFileSystem::DeviceStorageFileSystem(
- const nsAString& aStorageType,
- const nsAString& aStorageName)
+DeviceStorageFileSystem::DeviceStorageFileSystem(const nsAString& aStorageType,
+ const nsAString& aStorageName)
: mWindowId(0)
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
mStorageType = aStorageType;
mStorageName = aStorageName;
mRequiresPermissionChecks =
@@ -46,19 +45,16 @@ DeviceStorageFileSystem::DeviceStorageFi
getter_AddRefs(rootFile));
NS_WARN_IF(!rootFile || NS_FAILED(rootFile->GetPath(mLocalRootPath)));
if (!XRE_IsParentProcess()) {
return;
}
- FileSystemUtils::LocalPathToNormalizedPath(mLocalRootPath,
- mNormalizedLocalRootPath);
-
// DeviceStorageTypeChecker is a singleton object and must be initialized on
// the main thread. We initialize it here so that we can use it on the worker
// thread.
DebugOnly<DeviceStorageTypeChecker*> typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
MOZ_ASSERT(typeChecker);
}
@@ -100,22 +96,25 @@ DeviceStorageFileSystem::GetRootName(nsA
bool
DeviceStorageFileSystem::IsSafeFile(nsIFile* aFile) const
{
MOZ_ASSERT(XRE_IsParentProcess(),
"Should be on parent process!");
MOZ_ASSERT(aFile);
- // Check if this file belongs to this storage.
- nsAutoString path;
- if (NS_FAILED(aFile->GetPath(path))) {
+ nsCOMPtr<nsIFile> rootPath;
+ nsresult rv = NS_NewLocalFile(GetLocalRootPath(), false,
+ getter_AddRefs(rootPath));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
- if (!LocalPathToRealPath(path, path)) {
+
+ // Check if this file belongs to this storage.
+ if (NS_WARN_IF(!FileSystemUtils::IsDescendantPath(rootPath, aFile))) {
return false;
}
// Check if the file type is compatible with the storage type.
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
MOZ_ASSERT(typeChecker);
return typeChecker->Check(mStorageType, aFile);
--- a/dom/filesystem/Directory.cpp
+++ b/dom/filesystem/Directory.cpp
@@ -33,16 +33,22 @@
#endif
namespace mozilla {
namespace dom {
namespace {
bool
+TokenizerIgnoreNothing(char16_t /* aChar */)
+{
+ return false;
+}
+
+bool
IsValidRelativeDOMPath(const nsString& aPath, nsTArray<nsString>& aParts)
{
// We don't allow empty relative path to access the root.
if (aPath.IsEmpty()) {
return false;
}
// Leading and trailing "/" are not allowed.
@@ -50,17 +56,19 @@ IsValidRelativeDOMPath(const nsString& a
aPath.Last() == FILESYSTEM_DOM_PATH_SEPARATOR_CHAR) {
return false;
}
NS_NAMED_LITERAL_STRING(kCurrentDir, ".");
NS_NAMED_LITERAL_STRING(kParentDir, "..");
// Split path and check each path component.
- nsCharSeparatedTokenizer tokenizer(aPath, FILESYSTEM_DOM_PATH_SEPARATOR_CHAR);
+ nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing>
+ tokenizer(aPath, FILESYSTEM_DOM_PATH_SEPARATOR_CHAR);
+
while (tokenizer.hasMoreTokens()) {
nsDependentSubstring pathComponent = tokenizer.nextToken();
// The path containing empty components, such as "foo//bar", is invalid.
// We don't allow paths, such as "../foo", "foo/./bar" and "foo/../bar",
// to walk up the directory.
if (pathComponent.IsEmpty() ||
pathComponent.Equals(kCurrentDir) ||
pathComponent.Equals(kParentDir)) {
--- a/dom/filesystem/FileSystemBase.cpp
+++ b/dom/filesystem/FileSystemBase.cpp
@@ -94,25 +94,10 @@ FileSystemBase::IsSafeFile(nsIFile* aFil
}
bool
FileSystemBase::IsSafeDirectory(Directory* aDir) const
{
return false;
}
-bool
-FileSystemBase::LocalPathToRealPath(const nsAString& aLocalPath,
- nsAString& aRealPath) const
-{
- nsAutoString path;
- FileSystemUtils::LocalPathToNormalizedPath(aLocalPath, path);
- if (!FileSystemUtils::IsDescendantPath(mNormalizedLocalRootPath, path)) {
- aRealPath.Truncate();
- return false;
- }
-
- aRealPath = Substring(path, mNormalizedLocalRootPath.Length());
- return true;
-}
-
} // namespace dom
} // namespace mozilla
--- a/dom/filesystem/FileSystemBase.h
+++ b/dom/filesystem/FileSystemBase.h
@@ -82,28 +82,22 @@ public:
// CC methods
virtual void Unlink() {}
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) {}
protected:
virtual ~FileSystemBase();
- bool
- LocalPathToRealPath(const nsAString& aLocalPath, nsAString& aRealPath) const;
-
// The local path of the root (i.e. the OS path, with OS path separators, of
// the OS directory that acts as the root of this OSFileSystem).
// Only available in the parent process.
// In the child process, we don't use it and its value should be empty.
nsString mLocalRootPath;
- // The same, but with path separators normalized to "/".
- nsString mNormalizedLocalRootPath;
-
bool mShutdown;
// The permission name required to access the file system.
nsCString mPermission;
bool mRequiresPermissionChecks;
};
--- a/dom/filesystem/FileSystemPermissionRequest.cpp
+++ b/dom/filesystem/FileSystemPermissionRequest.cpp
@@ -10,31 +10,31 @@
#include "mozilla/dom/FileSystemUtils.h"
#include "nsIDocument.h"
#include "nsPIDOMWindow.h"
#include "nsContentPermissionHelper.h"
namespace mozilla {
namespace dom {
-NS_IMPL_ISUPPORTS(FileSystemPermissionRequest, nsIRunnable, nsIContentPermissionRequest)
+NS_IMPL_ISUPPORTS(FileSystemPermissionRequest, nsIRunnable,
+ nsIContentPermissionRequest)
// static
void
FileSystemPermissionRequest::RequestForTask(FileSystemTaskBase* aTask)
{
MOZ_ASSERT(aTask, "aTask should not be null!");
MOZ_ASSERT(NS_IsMainThread());
RefPtr<FileSystemPermissionRequest> request =
new FileSystemPermissionRequest(aTask);
NS_DispatchToCurrentThread(request);
}
-FileSystemPermissionRequest::FileSystemPermissionRequest(
- FileSystemTaskBase* aTask)
+FileSystemPermissionRequest::FileSystemPermissionRequest(FileSystemTaskBase* aTask)
: mTask(aTask)
{
MOZ_ASSERT(mTask, "aTask should not be null!");
MOZ_ASSERT(NS_IsMainThread());
mTask->GetPermissionAccessType(mPermissionAccess);
RefPtr<FileSystemBase> filesystem = mTask->GetFileSystem();
--- a/dom/filesystem/FileSystemTaskBase.cpp
+++ b/dom/filesystem/FileSystemTaskBase.cpp
@@ -18,17 +18,17 @@
#include "mozilla/unused.h"
#include "nsProxyRelease.h"
namespace mozilla {
namespace dom {
namespace {
-class FileSystemReleaseRunnable : public nsRunnable
+class FileSystemReleaseRunnable final : public nsRunnable
{
public:
explicit FileSystemReleaseRunnable(RefPtr<FileSystemBase>& aDoomed)
: mDoomed(nullptr)
{
aDoomed.swap(mDoomed);
}
--- a/dom/filesystem/FileSystemUtils.cpp
+++ b/dom/filesystem/FileSystemUtils.cpp
@@ -1,77 +1,20 @@
/* -*- 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/FileSystemUtils.h"
-#include "nsXULAppAPI.h"
-
namespace mozilla {
namespace dom {
-// static
-void
-FileSystemUtils::LocalPathToNormalizedPath(const nsAString& aLocal,
- nsAString& aNorm)
-{
- nsString result;
- result = aLocal;
-#if defined(XP_WIN)
- char16_t* cur = result.BeginWriting();
- char16_t* end = result.EndWriting();
- for (; cur < end; ++cur) {
- if (char16_t('\\') == *cur)
- *cur = char16_t('/');
- }
-#endif
- aNorm = result;
-}
-
-// static
-void
-FileSystemUtils::NormalizedPathToLocalPath(const nsAString& aNorm,
- nsAString& aLocal)
-{
- nsString result;
- result = aNorm;
-#if defined(XP_WIN)
- char16_t* cur = result.BeginWriting();
- char16_t* end = result.EndWriting();
- for (; cur < end; ++cur) {
- if (char16_t('/') == *cur)
- *cur = char16_t('\\');
- }
-#endif
- aLocal = result;
-}
-
-// static
-bool
-FileSystemUtils::IsDescendantPath(const nsAString& aPath,
- const nsAString& aDescendantPath)
-{
- // The descendant path should begin with its ancestor path.
- nsAutoString prefix;
- prefix = aPath + NS_LITERAL_STRING(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
-
- // Check the sub-directory path to see if it has the parent path as prefix.
- if (aDescendantPath.Length() < prefix.Length() ||
- !StringBeginsWith(aDescendantPath, prefix)) {
- return false;
- }
-
- return true;
-}
-
-// static
-bool
+/* static */ bool
FileSystemUtils::IsDescendantPath(nsIFile* aFile,
nsIFile* aDescendantFile)
{
nsAutoString path;
nsresult rv = aFile->GetPath(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
--- a/dom/filesystem/FileSystemUtils.h
+++ b/dom/filesystem/FileSystemUtils.h
@@ -2,54 +2,34 @@
/* 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_FileSystemUtils_h
#define mozilla_dom_FileSystemUtils_h
-#include "nsString.h"
+class nsIFile;
namespace mozilla {
namespace dom {
#define FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL "/"
#define FILESYSTEM_DOM_PATH_SEPARATOR_CHAR '/'
/*
* This class is for error handling.
* All methods in this class are static.
*/
class FileSystemUtils
{
public:
/*
- * Convert the path separator to "/".
- */
- static void
- LocalPathToNormalizedPath(const nsAString& aLocal, nsAString& aNorm);
-
- /*
- * Convert the normalized path separator "/" to the system dependent path
- * separator, which is "/" on Mac and Linux, and "\" on Windows.
- */
- static void
- NormalizedPathToLocalPath(const nsAString& aNorm, nsAString& aLocal);
-
- /*
* Return true if aDescendantPath is a descendant of aPath.
*/
static bool
IsDescendantPath(nsIFile* aPath, nsIFile* aDescendantPath);
-
- /*
- * Return true if aDescendantPath is a descendant of aPath. Both aPath and
- * aDescendantPath are absolute DOM path.
- */
- static bool
- IsDescendantPath(const nsAString& aPath, const nsAString& aDescendantPath);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FileSystemUtils_h
--- a/dom/filesystem/GetDirectoryListingTask.cpp
+++ b/dom/filesystem/GetDirectoryListingTask.cpp
@@ -123,25 +123,16 @@ GetDirectoryListingTask::GetRequestParam
return FileSystemGetDirectoryListingParams();
}
return FileSystemGetDirectoryListingParams(aSerializedDOMPath, path,
mType == Directory::eDOMRootDirectory,
mFilters);
}
-void
-GetDirectoryListingTask::CreateNormalizedRelativePath(const nsAString& aPath,
- nsAString& aRelativePath) const
-{
- uint32_t rootPathLen = mFileSystem->GetLocalRootPath().Length();
- FileSystemUtils::LocalPathToNormalizedPath(
- Substring(aPath, rootPathLen, aPath.Length() - rootPathLen), aRelativePath);
-}
-
FileSystemResponseValue
GetDirectoryListingTask::GetSuccessRequestResult(ErrorResult& aRv) const
{
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!");
InfallibleTArray<PBlobParent*> blobs;
nsTArray<FileSystemDirectoryListingResponseData> inputs;
@@ -361,20 +352,21 @@ GetDirectoryListingTask::HandlerCallback
mPromise->MaybeReject(rv);
mPromise = nullptr;
return;
}
MOZ_ASSERT(FileSystemUtils::IsDescendantPath(rootPath, directoryPath));
#endif
- RefPtr<Directory> directory = Directory::Create(mFileSystem->GetParentObject(),
- directoryPath,
- Directory::eNotDOMRootDirectory,
- mFileSystem);
+ RefPtr<Directory> directory =
+ Directory::Create(mFileSystem->GetParentObject(),
+ directoryPath,
+ Directory::eNotDOMRootDirectory,
+ mFileSystem);
MOZ_ASSERT(directory);
// Propogate mFilter onto sub-Directory object:
directory->SetContentFilters(mFilters);
listing[i].SetAsDirectory() = directory;
} else {
MOZ_ASSERT(mTargetData[i].mType == Directory::BlobImplOrDirectoryPath::eBlobImpl);
listing[i].SetAsFile() =
--- a/dom/filesystem/GetDirectoryListingTask.h
+++ b/dom/filesystem/GetDirectoryListingTask.h
@@ -65,20 +65,16 @@ private:
ErrorResult& aRv) override;
virtual nsresult
Work() override;
virtual void
HandlerCallback() override;
- void
- CreateNormalizedRelativePath(const nsAString& aPath,
- nsAString& aRelativePath) const;
-
RefPtr<Promise> mPromise;
nsCOMPtr<nsIFile> mTargetPath;
nsString mFilters;
Directory::DirectoryType mType;
// We cannot store File or Directory objects bacause this object is created
// on a different thread and File and Directory are not thread-safe.
nsTArray<Directory::BlobImplOrDirectoryPath> mTargetData;
--- a/dom/filesystem/OSFileSystem.cpp
+++ b/dom/filesystem/OSFileSystem.cpp
@@ -15,18 +15,16 @@
#include "nsIFile.h"
namespace mozilla {
namespace dom {
OSFileSystem::OSFileSystem(const nsAString& aRootDir)
{
mLocalRootPath = aRootDir;
- FileSystemUtils::LocalPathToNormalizedPath(mLocalRootPath,
- mNormalizedLocalRootPath);
// Non-mobile devices don't have the concept of separate permissions to
// access different parts of devices storage like Pictures, or Videos, etc.
mRequiresPermissionChecks = false;
#ifdef DEBUG
mPermission.AssignLiteral("never-used");
#endif