Bug 1173320 - patch 5/8 - Cleanup manual string path management, r=smaug
☠☠ backed out by bd8284e36c7c ☠ ☠
authorAndrea Marchesini <amarchesini@mozilla.com>
Sat, 19 Mar 2016 14:34:05 +0100
changeset 289463 56bbea4fe19990be2b05cd31371e76c01a252fc5
parent 289462 e94ced2f8e3cf5e639924b1800f93f1e79f4b1a9
child 289464 cd7e79d9a7507c6b33744428632dc684c2a82e10
push id30102
push userryanvm@gmail.com
push dateSat, 19 Mar 2016 15:23:17 +0000
treeherdermozilla-central@720fb3d55e28 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1173320
milestone48.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1173320 - patch 5/8 - Cleanup manual string path management, r=smaug
dom/devicestorage/DeviceStorage.h
dom/devicestorage/nsDeviceStorage.cpp
dom/filesystem/CreateFileTask.cpp
dom/filesystem/DeviceStorageFileSystem.cpp
dom/filesystem/Directory.cpp
dom/filesystem/FileSystemBase.cpp
dom/filesystem/FileSystemBase.h
dom/filesystem/FileSystemPermissionRequest.cpp
dom/filesystem/FileSystemTaskBase.cpp
dom/filesystem/FileSystemUtils.cpp
dom/filesystem/FileSystemUtils.h
dom/filesystem/GetDirectoryListingTask.cpp
dom/filesystem/GetDirectoryListingTask.h
dom/filesystem/OSFileSystem.cpp
--- 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