tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DirectoryMetadata.cpp (4150B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "DirectoryMetadata.h"
      8 
      9 #include "mozilla/Result.h"
     10 #include "mozilla/TypedEnumBits.h"
     11 #include "mozilla/dom/quota/Assertions.h"
     12 #include "mozilla/dom/quota/CommonMetadata.h"
     13 #include "mozilla/dom/quota/QuotaCommon.h"
     14 #include "mozilla/dom/quota/ResultExtensions.h"
     15 #include "mozilla/dom/quota/StreamUtils.h"
     16 #include "nsIBinaryInputStream.h"
     17 #include "nsIBinaryOutputStream.h"
     18 
     19 namespace mozilla::dom::quota {
     20 
     21 // clang-format off
     22 
     23 enum class DirectoryMetadataFlags : uint32_t {
     24  None        = 0,
     25  Initialized = 1 << 0,
     26  Accessed    = 1 << 1,
     27 };
     28 
     29 // clang-format on
     30 
     31 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DirectoryMetadataFlags)
     32 
     33 Result<OriginStateMetadata, nsresult> ReadDirectoryMetadataHeader(
     34    nsIBinaryInputStream& aStream) {
     35  AssertIsOnIOThread();
     36 
     37  OriginStateMetadata originStateMetadata;
     38 
     39  QM_TRY_UNWRAP(originStateMetadata.mLastAccessTime,
     40                MOZ_TO_RESULT_INVOKE_MEMBER(aStream, Read64));
     41 
     42  QM_TRY_UNWRAP(originStateMetadata.mPersisted,
     43                MOZ_TO_RESULT_INVOKE_MEMBER(aStream, ReadBoolean));
     44 
     45  QM_TRY_INSPECT(const uint32_t& rawFlags,
     46                 MOZ_TO_RESULT_INVOKE_MEMBER(aStream, Read32));
     47 
     48  auto flags = static_cast<DirectoryMetadataFlags>(rawFlags);
     49 
     50  // If DirectoryMetadataFlags::Initialized is not set, the flags field
     51  // contains no valid data. Since mAccessed indicates whether a full scan must
     52  // be done during initialization, we conservatively set it to true when the
     53  // access state is unknown.
     54  originStateMetadata.mAccessed =
     55      rawFlags == 0 || (flags & DirectoryMetadataFlags::Accessed) !=
     56                           DirectoryMetadataFlags::None;
     57 
     58  QM_TRY_UNWRAP(originStateMetadata.mLastMaintenanceDate,
     59                MOZ_TO_RESULT_INVOKE_MEMBER(aStream, Read32));
     60 
     61  return originStateMetadata;
     62 }
     63 
     64 nsresult WriteDirectoryMetadataHeader(
     65    nsIBinaryOutputStream& aStream,
     66    const OriginStateMetadata& aOriginStateMetadata) {
     67  AssertIsOnIOThread();
     68 
     69  QM_TRY(MOZ_TO_RESULT(aStream.Write64(aOriginStateMetadata.mLastAccessTime)));
     70 
     71  QM_TRY(MOZ_TO_RESULT(aStream.WriteBoolean(aOriginStateMetadata.mPersisted)));
     72 
     73  // Always set DirectoryMetadataFlags::Initialized when writing new metadata,
     74  // to mark the flags field as valid. This distinguishes real flags from older
     75  // files where the field was reserved and always written as zero.
     76  auto flags =
     77      DirectoryMetadataFlags::Initialized |
     78      (aOriginStateMetadata.mAccessed ? DirectoryMetadataFlags::Accessed
     79                                      : DirectoryMetadataFlags::None);
     80 
     81  auto rawFlags = static_cast<uint32_t>(flags);
     82 
     83  QM_TRY(MOZ_TO_RESULT(aStream.Write32(rawFlags)));
     84 
     85  QM_TRY(MOZ_TO_RESULT(
     86      aStream.Write32(aOriginStateMetadata.mLastMaintenanceDate)));
     87 
     88  return NS_OK;
     89 }
     90 
     91 Result<OriginStateMetadata, nsresult> LoadDirectoryMetadataHeader(
     92    nsIFile& aDirectory) {
     93  AssertIsOnIOThread();
     94 
     95  QM_TRY_INSPECT(
     96      const auto& stream,
     97      GetBinaryInputStream(aDirectory, nsLiteralString(METADATA_V2_FILE_NAME)));
     98 
     99  QM_TRY_INSPECT(const OriginStateMetadata& originStateMetadata,
    100                 ReadDirectoryMetadataHeader(*stream));
    101 
    102  QM_TRY(MOZ_TO_RESULT(stream->Close()));
    103 
    104  return originStateMetadata;
    105 }
    106 
    107 nsresult SaveDirectoryMetadataHeader(
    108    nsIFile& aDirectory, const OriginStateMetadata& aOriginStateMetadata) {
    109  AssertIsOnIOThread();
    110 
    111  QM_TRY_INSPECT(
    112      const auto& file,
    113      CloneFileAndAppend(aDirectory, nsLiteralString(METADATA_V2_FILE_NAME)));
    114 
    115  QM_TRY_INSPECT(const auto& stream,
    116                 GetBinaryOutputStream(*file, FileFlag::Update));
    117  MOZ_ASSERT(stream);
    118 
    119  QM_TRY(MOZ_TO_RESULT(
    120      WriteDirectoryMetadataHeader(*stream, aOriginStateMetadata)));
    121 
    122  QM_TRY(MOZ_TO_RESULT(stream->Flush()));
    123 
    124  QM_TRY(MOZ_TO_RESULT(stream->Close()));
    125 
    126  return NS_OK;
    127 }
    128 
    129 }  // namespace mozilla::dom::quota