Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/dom/filesystem/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 12 kB image not shown  

SSL GetDirectoryListingTask.cpp   Interaktion und
PortierbarkeitC

 
/* -*- 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 "GetDirectoryListingTask.h"

#include "HTMLSplitOnSpacesTokenizer.h"
#include "js/Value.h"
#include "mozilla/dom/FileBlobImpl.h"
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/PFileSystemParams.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "nsCExternalHandlerService.h"
#include "nsIFile.h"
#include "nsIMIMEService.h"
#include "nsString.h"

namespace mozilla::dom {

/**
 * GetDirectoryListingTaskChild
 */


/* static */
already_AddRefed<GetDirectoryListingTaskChild>
GetDirectoryListingTaskChild::Create(FileSystemBase* aFileSystem,
                                     Directory* aDirectory,
                                     nsIFile* aTargetPath,
                                     const nsAString& aFilters,
                                     ErrorResult& aRv) {
  MOZ_ASSERT(aFileSystem);
  MOZ_ASSERT(aDirectory);
  aFileSystem->AssertIsOnOwningThread();

  nsCOMPtr<nsIGlobalObject> globalObject = aFileSystem->GetParentObject();
  MOZ_ASSERT(globalObject);

  RefPtr<GetDirectoryListingTaskChild> task = new GetDirectoryListingTaskChild(
      globalObject, aFileSystem, aDirectory, aTargetPath, aFilters);

  // aTargetPath can be null. In this case SetError will be called.

  task->mPromise = Promise::Create(globalObject, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  return task.forget();
}

GetDirectoryListingTaskChild::GetDirectoryListingTaskChild(
    nsIGlobalObject* aGlobalObject, FileSystemBase* aFileSystem,
    Directory* aDirectory, nsIFile* aTargetPath, const nsAString& aFilters)
    : FileSystemTaskChildBase(aGlobalObject, aFileSystem),
      mDirectory(aDirectory),
      mTargetPath(aTargetPath),
      mFilters(aFilters) {
  MOZ_ASSERT(aFileSystem);
  aFileSystem->AssertIsOnOwningThread();
}

GetDirectoryListingTaskChild::~GetDirectoryListingTaskChild() {
  mFileSystem->AssertIsOnOwningThread();
}

already_AddRefed<Promise> GetDirectoryListingTaskChild::GetPromise() {
  mFileSystem->AssertIsOnOwningThread();
  return RefPtr<Promise>(mPromise).forget();
}

FileSystemParams GetDirectoryListingTaskChild::GetRequestParams(
    const nsString& aSerializedDOMPath, ErrorResult& aRv) const {
  mFileSystem->AssertIsOnOwningThread();

  // this is the real path.
  nsAutoString path;
  aRv = mTargetPath->GetPath(path);
  if (NS_WARN_IF(aRv.Failed())) {
    return FileSystemGetDirectoryListingParams();
  }

  // this is the dom path.
  nsAutoString directoryPath;
  mDirectory->GetPath(directoryPath, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return FileSystemGetDirectoryListingParams();
  }

  return FileSystemGetDirectoryListingParams(aSerializedDOMPath, path,
                                             directoryPath, mFilters);
}

void GetDirectoryListingTaskChild::SetSuccessRequestResult(
    const FileSystemResponseValue& aValue, ErrorResult& aRv) {
  mFileSystem->AssertIsOnOwningThread();
  MOZ_ASSERT(aValue.type() ==
             FileSystemResponseValue::TFileSystemDirectoryListingResponse);

  FileSystemDirectoryListingResponse r = aValue;
  for (uint32_t i = 0; i < r.data().Length(); ++i) {
    const FileSystemDirectoryListingResponseData& data = r.data()[i];

    OwningFileOrDirectory* ofd = mTargetData.AppendElement(fallible);
    if (!ofd) {
      aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
      return;
    }

    if (data.type() == FileSystemDirectoryListingResponseData::
                           TFileSystemDirectoryListingResponseFile) {
      const FileSystemDirectoryListingResponseFile& d =
          data.get_FileSystemDirectoryListingResponseFile();

      RefPtr<BlobImpl> blobImpl = IPCBlobUtils::Deserialize(d.blob());
      MOZ_ASSERT(blobImpl);

      nsCOMPtr<nsIGlobalObject> globalObject = mFileSystem->GetParentObject();
      MOZ_ASSERT(globalObject);

      RefPtr<File> file = File::Create(globalObject, blobImpl);
      MOZ_ASSERT(file);

      ofd->SetAsFile() = file;
    } else {
      MOZ_ASSERT(data.type() ==
                 FileSystemDirectoryListingResponseData::
                     TFileSystemDirectoryListingResponseDirectory);
      const FileSystemDirectoryListingResponseDirectory& d =
          data.get_FileSystemDirectoryListingResponseDirectory();

      nsCOMPtr<nsIFile> path;
      aRv = NS_NewLocalFile(d.directoryRealPath(), getter_AddRefs(path));
      if (NS_WARN_IF(aRv.Failed())) {
        return;
      }

      RefPtr<Directory> directory =
          Directory::Create(mFileSystem->GetParentObject(), path, mFileSystem);
      MOZ_ASSERT(directory);

      ofd->SetAsDirectory() = directory;
    }
  }
}

void GetDirectoryListingTaskChild::HandlerCallback() {
  mFileSystem->AssertIsOnOwningThread();

  if (mFileSystem->IsShutdown()) {
    mPromise = nullptr;
    return;
  }

  if (HasError()) {
    mPromise->MaybeReject(mErrorValue);
    mPromise = nullptr;
    return;
  }

  mPromise->MaybeResolve(mTargetData);
  mPromise = nullptr;
}

/**
 * GetDirectoryListingTaskParent
 */


/* static */
already_AddRefed<GetDirectoryListingTaskParent>
GetDirectoryListingTaskParent::Create(
    FileSystemBase* aFileSystem,
    const FileSystemGetDirectoryListingParams& aParam,
    FileSystemRequestParent* aParent, ErrorResult& aRv) {
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
  mozilla::ipc::AssertIsOnBackgroundThread();
  MOZ_ASSERT(aFileSystem);

  RefPtr<GetDirectoryListingTaskParent> task =
      new GetDirectoryListingTaskParent(aFileSystem, aParam, aParent);

  aRv = NS_NewLocalFile(aParam.realPath(), getter_AddRefs(task->mTargetPath));
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  return task.forget();
}

GetDirectoryListingTaskParent::GetDirectoryListingTaskParent(
    FileSystemBase* aFileSystem,
    const FileSystemGetDirectoryListingParams& aParam,
    FileSystemRequestParent* aParent)
    : FileSystemTaskParentBase(aFileSystem, aParam, aParent),
      mDOMPath(aParam.domPath()),
      mFilters(aParam.filters()) {
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
  mozilla::ipc::AssertIsOnBackgroundThread();
  MOZ_ASSERT(aFileSystem);
}

FileSystemResponseValue GetDirectoryListingTaskParent::GetSuccessRequestResult(
    ErrorResult& aRv) const {
  mozilla::ipc::AssertIsOnBackgroundThread();

  nsTArray<FileSystemDirectoryListingResponseData> inputs;

  for (unsigned i = 0; i < mTargetData.Length(); i++) {
    if (mTargetData[i].mType == FileOrDirectoryPath::eFilePath) {
      nsCOMPtr<nsIFile> path;
      nsresult rv = NS_NewLocalFile(mTargetData[i].mPath, getter_AddRefs(path));
      if (NS_WARN_IF(NS_FAILED(rv))) {
        continue;
      }

      nsAutoString fileName;
      path->GetLeafName(fileName);

      int64_t fileSize = 0;
      rv = path->GetFileSize(&fileSize);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        continue;
      }

      FileSystemDirectoryListingResponseFile fileData;
      RefPtr<BlobImpl> blobImpl = new FileBlobImpl(
          fileName, mTargetData[i].mContentType, fileSize, path);

      nsAutoString filePath;
      filePath.Assign(mDOMPath);

      // This is specific for unix root filesystem.
      if (!mDOMPath.EqualsLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL)) {
        filePath.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
      }

      nsAutoString name;
      blobImpl->GetName(name);
      filePath.Append(name);
      blobImpl->SetDOMPath(filePath);

      IPCBlob ipcBlob;
      rv = IPCBlobUtils::Serialize(blobImpl, ipcBlob);
      if (NS_WARN_IF(NS_FAILED(rv))) {
        continue;
      }

      fileData.blob() = ipcBlob;
      inputs.AppendElement(fileData);
    } else {
      MOZ_ASSERT(mTargetData[i].mType == FileOrDirectoryPath::eDirectoryPath);
      FileSystemDirectoryListingResponseDirectory directoryData;
      directoryData.directoryRealPath() = mTargetData[i].mPath;
      inputs.AppendElement(directoryData);
    }
  }

  FileSystemDirectoryListingResponse response;
  response.data() = std::move(inputs);
  return response;
}

nsresult GetDirectoryListingTaskParent::IOWork() {
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
  MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!");

  if (mFileSystem->IsShutdown()) {
    return NS_ERROR_FAILURE;
  }

  bool exists;
  nsresult rv = mTargetPath->Exists(&exists);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (!exists) {
    if (!mFileSystem->ShouldCreateDirectory()) {
      return NS_ERROR_DOM_FILE_NOT_FOUND_ERR;
    }

    rv = mTargetPath->Create(nsIFile::DIRECTORY_TYPE, 0777);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }

  // Get isDirectory.
  bool isDir;
  rv = mTargetPath->IsDirectory(&isDir);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (!isDir) {
    return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR;
  }

  nsCOMPtr<nsIDirectoryEnumerator> entries;
  rv = mTargetPath->GetDirectoryEntries(getter_AddRefs(entries));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  bool filterOutSensitive = false;
  {
    HTMLSplitOnSpacesTokenizer tokenizer(mFilters, ';');
    nsAutoString token;
    while (tokenizer.hasMoreTokens()) {
      token = tokenizer.nextToken();
      if (token.EqualsLiteral("filter-out-sensitive")) {
        filterOutSensitive = true;
      } else {
        MOZ_CRASH("Unrecognized filter");
      }
    }
  }

  for (;;) {
    nsCOMPtr<nsIFile> currFile;
    if (NS_WARN_IF(NS_FAILED(entries->GetNextFile(getter_AddRefs(currFile)))) ||
        !currFile) {
      break;
    }
    bool isLink, isSpecial, isFile;
    if (NS_WARN_IF(NS_FAILED(currFile->IsSymlink(&isLink)) ||
                   NS_FAILED(currFile->IsSpecial(&isSpecial))) ||
        // Although we allow explicit individual selection of symlinks via the
        // file picker, we do not process symlinks in directory traversal.  Our
        // specific policy decision is documented at
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1813299#c20
        isLink || isSpecial) {
      continue;
    }
    if (NS_WARN_IF(NS_FAILED(currFile->IsFile(&isFile)) ||
                   NS_FAILED(currFile->IsDirectory(&isDir))) ||
        !(isFile || isDir)) {
      continue;
    }

    if (filterOutSensitive) {
      bool isHidden;
      if (NS_WARN_IF(NS_FAILED(currFile->IsHidden(&isHidden))) || isHidden) {
        continue;
      }
      nsAutoString leafName;
      if (NS_WARN_IF(NS_FAILED(currFile->GetLeafName(leafName)))) {
        continue;
      }
      if (leafName[0] == char16_t('.')) {
        continue;
      }
    }

    nsAutoString path;
    if (NS_WARN_IF(NS_FAILED(currFile->GetPath(path)))) {
      continue;
    }

    FileOrDirectoryPath element;
    element.mPath = path;
    element.mType = isDir ? FileOrDirectoryPath::eDirectoryPath
                          : FileOrDirectoryPath::eFilePath;

    if (!mTargetData.AppendElement(element, fallible)) {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
  return NS_OK;
}

nsresult GetDirectoryListingTaskParent::MainThreadWork() {
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");
  MOZ_ASSERT(NS_IsMainThread(), "Only call on main-thread!");

  nsresult rv;
  nsCOMPtr<nsIMIMEService> mimeService =
      do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  for (unsigned i = 0; i < mTargetData.Length(); i++) {
    if (mTargetData[i].mType != FileOrDirectoryPath::eFilePath) {
      continue;
    }

    nsCOMPtr<nsIFile> file;
    nsresult rv = NS_NewLocalFile(mTargetData[i].mPath, getter_AddRefs(file));
    if (NS_WARN_IF(NS_FAILED(rv))) {
      continue;
    }

    nsAutoCString mimeType;
    rv = mimeService->GetTypeFromFile(file, mimeType);
    if (NS_FAILED(rv)) {
      mimeType.Truncate();
    }

    AppendUTF8toUTF16(mimeType, mTargetData[i].mContentType);
  }

  return NS_OK;
}

bool GetDirectoryListingTaskParent::MainThreadNeeded() const {
  MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!");

  // We need to go to the main-thread only if we have files in the list of
  // target.
  for (const FileOrDirectoryPath& data : mTargetData) {
    if (data.mType == FileOrDirectoryPath::eFilePath) {
      return true;
    }
  }

  return false;
}

nsresult GetDirectoryListingTaskParent::GetTargetPath(nsAString& aPath) const {
  return mTargetPath->GetPath(aPath);
}

}  // namespace mozilla::dom

90%


¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.0Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.