tor-browser

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

TestBase64Stream.cpp (3404B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "gtest/gtest.h"
      7 #include "mozilla/Base64.h"
      8 #include "mozilla/gtest/MozAssertions.h"
      9 #include "nsCOMPtr.h"
     10 #include "nsIInputStream.h"
     11 #include "nsStringStream.h"
     12 
     13 namespace mozilla {
     14 namespace net {
     15 
     16 // An input stream whose ReadSegments method calls aWriter with writes of size
     17 // aStep from the provided aInput in order to test edge-cases related to small
     18 // buffers.
     19 class TestStream final : public nsIInputStream {
     20 public:
     21  NS_DECL_ISUPPORTS;
     22 
     23  TestStream(const nsACString& aInput, uint32_t aStep)
     24      : mInput(aInput), mStep(aStep) {}
     25 
     26  NS_IMETHOD Close() override { MOZ_CRASH("This should not be called"); }
     27 
     28  NS_IMETHOD Available(uint64_t* aLength) override {
     29    *aLength = mInput.Length() - mPos;
     30    return NS_OK;
     31  }
     32 
     33  NS_IMETHOD StreamStatus() override { return NS_OK; }
     34 
     35  NS_IMETHOD Read(char* aBuffer, uint32_t aCount,
     36                  uint32_t* aReadCount) override {
     37    MOZ_CRASH("This should not be called");
     38  }
     39 
     40  NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
     41                          uint32_t aCount, uint32_t* aResult) override {
     42    *aResult = 0;
     43 
     44    if (mPos == mInput.Length()) {
     45      return NS_OK;
     46    }
     47 
     48    while (aCount > 0) {
     49      uint32_t amt = std::min(mStep, (uint32_t)(mInput.Length() - mPos));
     50 
     51      uint32_t read = 0;
     52      nsresult rv =
     53          aWriter(this, aClosure, mInput.get() + mPos, *aResult, amt, &read);
     54      if (NS_WARN_IF(NS_FAILED(rv))) {
     55        return rv;
     56      }
     57 
     58      *aResult += read;
     59      aCount -= read;
     60      mPos += read;
     61    }
     62 
     63    return NS_OK;
     64  }
     65 
     66  NS_IMETHOD IsNonBlocking(bool* aNonBlocking) override {
     67    *aNonBlocking = true;
     68    return NS_OK;
     69  }
     70 
     71 private:
     72  ~TestStream() = default;
     73 
     74  nsCString mInput;
     75  const uint32_t mStep;
     76  uint32_t mPos = 0;
     77 };
     78 
     79 NS_IMPL_ISUPPORTS(TestStream, nsIInputStream)
     80 
     81 // Test the base64 encoder with writer buffer sizes between 1 byte and the
     82 // entire length of "Hello World!" in order to exercise various edge cases.
     83 TEST(TestBase64Stream, Run)
     84 {
     85  nsCString input;
     86  input.AssignLiteral("Hello World!");
     87 
     88  for (uint32_t step = 1; step <= input.Length(); ++step) {
     89    RefPtr<TestStream> ts = new TestStream(input, step);
     90 
     91    nsAutoString encodedData;
     92    nsresult rv = Base64EncodeInputStream(ts, encodedData, input.Length());
     93    ASSERT_NS_SUCCEEDED(rv);
     94 
     95    EXPECT_TRUE(encodedData.EqualsLiteral("SGVsbG8gV29ybGQh"));
     96  }
     97 }
     98 
     99 TEST(TestBase64Stream, VaryingCount)
    100 {
    101  nsCString input;
    102  input.AssignLiteral("Hello World!");
    103 
    104  std::pair<size_t, nsCString> tests[] = {
    105      {0, "SGVsbG8gV29ybGQh"_ns},  {1, "SA=="_ns},
    106      {5, "SGVsbG8="_ns},          {11, "SGVsbG8gV29ybGQ="_ns},
    107      {12, "SGVsbG8gV29ybGQh"_ns}, {13, "SGVsbG8gV29ybGQh"_ns},
    108  };
    109 
    110  for (auto& [count, expected] : tests) {
    111    nsCOMPtr<nsIInputStream> is;
    112    nsresult rv = NS_NewCStringInputStream(getter_AddRefs(is), input);
    113    ASSERT_NS_SUCCEEDED(rv);
    114 
    115    nsAutoCString encodedData;
    116    rv = Base64EncodeInputStream(is, encodedData, count);
    117    ASSERT_NS_SUCCEEDED(rv);
    118    EXPECT_EQ(encodedData, expected) << "count: " << count;
    119  }
    120 }
    121 
    122 }  // namespace net
    123 }  // namespace mozilla