tor-browser

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

TestFileSystemHashSource.cpp (5675B)


      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 "FileSystemHashSource.h"
      8 #include "FileSystemParentTypes.h"
      9 #include "TestHelpers.h"
     10 #include "gtest/gtest.h"
     11 #include "mozilla/Array.h"
     12 #include "mozilla/dom/FileSystemTypes.h"
     13 #include "nsContentUtils.h"
     14 #include "nsLiteralString.h"
     15 #include "nsString.h"
     16 #include "nsStringFwd.h"
     17 #include "nsTArray.h"
     18 #include "nsTHashSet.h"
     19 
     20 namespace mozilla::dom::fs::test {
     21 
     22 using mozilla::dom::fs::data::FileSystemHashSource;
     23 
     24 namespace {
     25 
     26 constexpr size_t sha256ByteLength = 32u;
     27 
     28 constexpr size_t kExpectedLength = 52u;
     29 
     30 std::wstring asWide(const nsString& aStr) {
     31  std::wstring result;
     32  result.reserve(aStr.Length());
     33  for (const auto* it = aStr.BeginReading(); it != aStr.EndReading(); ++it) {
     34    result.push_back(static_cast<wchar_t>(*it));
     35  }
     36  return result;
     37 }
     38 
     39 }  // namespace
     40 
     41 TEST(TestFileSystemHashSource, isHashLengthAsExpected)
     42 {
     43  EntryId parent = "a"_ns;
     44  Name name = u"b"_ns;
     45  TEST_TRY_UNWRAP(EntryId result,
     46                  FileSystemHashSource::GenerateHash(parent, name));
     47  ASSERT_EQ(sha256ByteLength, result.Length());
     48 };
     49 
     50 TEST(TestFileSystemHashSource, areNestedNameHashesValidAndUnequal)
     51 {
     52  EntryId emptyParent = ""_ns;
     53  Name name = u"a"_ns;
     54  const size_t nestingNumber = 500u;
     55 
     56  nsTHashSet<EntryId> results;
     57  nsTHashSet<Name> names;
     58 
     59  auto previousParent = emptyParent;
     60  for (size_t i = 0; i < nestingNumber; ++i) {
     61    TEST_TRY_UNWRAP(EntryId result,
     62                    FileSystemHashSource::GenerateHash(previousParent, name));
     63 
     64    TEST_TRY_UNWRAP(Name encoded,
     65                    FileSystemHashSource::EncodeHash(FileId(result)));
     66 
     67    // Validity checks
     68    ASSERT_TRUE(mozilla::IsAscii(encoded))
     69    << encoded;
     70    Name upperCaseVersion;
     71    nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion);
     72    ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str());
     73 
     74    // Is the same hash encountered?
     75    ASSERT_FALSE(results.Contains(result));
     76    ASSERT_TRUE(results.Insert(result, mozilla::fallible));
     77 
     78    // Is the same name encountered?
     79    ASSERT_FALSE(names.Contains(encoded));
     80    ASSERT_TRUE(names.Insert(encoded, mozilla::fallible));
     81 
     82    previousParent = result;
     83  }
     84 };
     85 
     86 TEST(TestFileSystemHashSource, areNameCombinationHashesUnequal)
     87 {
     88  EntryId emptyParent = ""_ns;
     89 
     90  mozilla::Array<Name, 2> inputs = {u"a"_ns, u"b"_ns};
     91  nsTArray<EntryId> results;
     92  nsTArray<Name> names;
     93 
     94  for (const auto& name : inputs) {
     95    TEST_TRY_UNWRAP(EntryId result,
     96                    FileSystemHashSource::GenerateHash(emptyParent, name));
     97    TEST_TRY_UNWRAP(Name encoded,
     98                    FileSystemHashSource::EncodeHash(FileId(result)));
     99 
    100    // Validity checks
    101    ASSERT_TRUE(mozilla::IsAscii(encoded))
    102    << encoded;
    103    Name upperCaseVersion;
    104    nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion);
    105    ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str());
    106 
    107    results.AppendElement(result);
    108    names.AppendElement(encoded);
    109  }
    110 
    111  nsTArray<EntryId> more_results;
    112  nsTArray<Name> more_names;
    113  for (const auto& parent : results) {
    114    for (const auto& name : inputs) {
    115      TEST_TRY_UNWRAP(EntryId result,
    116                      FileSystemHashSource::GenerateHash(parent, name));
    117      TEST_TRY_UNWRAP(Name encoded,
    118                      FileSystemHashSource::EncodeHash(FileId(result)));
    119 
    120      // Validity checks
    121      ASSERT_TRUE(mozilla::IsAscii(encoded))
    122      << encoded;
    123      Name upperCaseVersion;
    124      nsContentUtils::ASCIIToUpper(encoded, upperCaseVersion);
    125      ASSERT_STREQ(asWide(upperCaseVersion).c_str(), asWide(encoded).c_str());
    126 
    127      more_results.AppendElement(result);
    128      more_names.AppendElement(encoded);
    129    }
    130  }
    131 
    132  results.AppendElements(more_results);
    133  names.AppendElements(more_names);
    134 
    135  // Is the same hash encountered?
    136  for (size_t i = 0; i < results.Length(); ++i) {
    137    for (size_t j = i + 1; j < results.Length(); ++j) {
    138      ASSERT_STRNE(results[i].get(), results[j].get());
    139    }
    140  }
    141 
    142  // Is the same name encountered?
    143  for (size_t i = 0; i < names.Length(); ++i) {
    144    for (size_t j = i + 1; j < names.Length(); ++j) {
    145      ASSERT_STRNE(asWide(names[i]).c_str(), asWide(names[j]).c_str());
    146    }
    147  }
    148 };
    149 
    150 TEST(TestFileSystemHashSource, encodeGeneratedHash)
    151 {
    152  Name expected = u"HF6FOFV72G3NMDEJKYMVRIFJO4X5ZNZCF2GM7Q4Y5Q3E7NPQKSLA"_ns;
    153  ASSERT_EQ(kExpectedLength, expected.Length());
    154 
    155  EntryId parent = "a"_ns;
    156  Name name = u"b"_ns;
    157  TEST_TRY_UNWRAP(EntryId entry,
    158                  FileSystemHashSource::GenerateHash(parent, name));
    159  ASSERT_EQ(sha256ByteLength, entry.Length());
    160 
    161  TEST_TRY_UNWRAP(Name result, FileSystemHashSource::EncodeHash(FileId(entry)));
    162  ASSERT_EQ(kExpectedLength, result.Length());
    163  ASSERT_STREQ(asWide(expected).c_str(), asWide(result).c_str());
    164 
    165  // Generate further hashes
    166  TEST_TRY_UNWRAP(entry, FileSystemHashSource::GenerateHash(entry, result));
    167  ASSERT_EQ(sha256ByteLength, entry.Length());
    168 
    169  TEST_TRY_UNWRAP(result, FileSystemHashSource::EncodeHash(FileId(entry)));
    170 
    171  // Always the same length
    172  ASSERT_EQ(kExpectedLength, result.Length());
    173 
    174  // Encoded versions should differ
    175  ASSERT_STRNE(asWide(expected).c_str(), asWide(result).c_str());
    176 
    177  // Padding length should have been stripped
    178  char16_t padding = u"="_ns[0];
    179  const int32_t paddingStart = result.FindChar(padding);
    180  ASSERT_EQ(-1, paddingStart);
    181 };
    182 
    183 }  // namespace mozilla::dom::fs::test