xref: /llvm-project/llvm/unittests/Support/Base64Test.cpp (revision ea9ac3519c13ee702e5d55a0eb570caf67a21999)
1 //===- llvm/unittest/Support/Base64Test.cpp - Base64 tests
2 //--------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements unit tests for the Base64 functions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/Base64.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/Testing/Support/Error.h"
17 #include "gtest/gtest.h"
18 
19 using namespace llvm;
20 
21 namespace {
22 /// Tests an arbitrary set of bytes passed as \p Input.
TestBase64(StringRef Input,StringRef Final)23 void TestBase64(StringRef Input, StringRef Final) {
24   auto Res = encodeBase64(Input);
25   EXPECT_EQ(Res, Final);
26 }
27 
TestBase64Decode(StringRef Input,StringRef Expected,StringRef ExpectedErrorMessage={})28 void TestBase64Decode(StringRef Input, StringRef Expected,
29                       StringRef ExpectedErrorMessage = {}) {
30   std::vector<char> DecodedBytes;
31   if (ExpectedErrorMessage.empty()) {
32     ASSERT_THAT_ERROR(decodeBase64(Input, DecodedBytes), Succeeded());
33     EXPECT_EQ(llvm::ArrayRef<char>(DecodedBytes),
34               llvm::ArrayRef<char>(Expected.data(), Expected.size()));
35   } else {
36     ASSERT_THAT_ERROR(decodeBase64(Input, DecodedBytes),
37                       FailedWithMessage(ExpectedErrorMessage));
38   }
39 }
40 
41 char NonPrintableVector[] = {0x00, 0x00, 0x00,       0x46,
42                              0x00, 0x08, (char)0xff, (char)0xee};
43 
44 char LargeVector[] = {0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6b,
45                       0x20, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f,
46                       0x78, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x73, 0x20, 0x6f,
47                       0x76, 0x65, 0x72, 0x20, 0x31, 0x33, 0x20, 0x6c, 0x61,
48                       0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67, 0x73, 0x2e};
49 
50 } // namespace
51 
TEST(Base64Test,Base64)52 TEST(Base64Test, Base64) {
53   // from: https://tools.ietf.org/html/rfc4648#section-10
54   TestBase64("", "");
55   TestBase64("f", "Zg==");
56   TestBase64("fo", "Zm8=");
57   TestBase64("foo", "Zm9v");
58   TestBase64("foob", "Zm9vYg==");
59   TestBase64("fooba", "Zm9vYmE=");
60   TestBase64("foobar", "Zm9vYmFy");
61 
62   // With non-printable values.
63   TestBase64({NonPrintableVector, sizeof(NonPrintableVector)}, "AAAARgAI/+4=");
64 
65   // Large test case
66   TestBase64({LargeVector, sizeof(LargeVector)},
67              "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIDEzIGxhenkgZG9ncy4=");
68 }
69 
TEST(Base64Test,DecodeBase64)70 TEST(Base64Test, DecodeBase64) {
71   std::vector<llvm::StringRef> Outputs = {"",     "f",     "fo",    "foo",
72                                           "foob", "fooba", "foobar"};
73   Outputs.push_back(
74       llvm::StringRef(NonPrintableVector, sizeof(NonPrintableVector)));
75 
76   Outputs.push_back(llvm::StringRef(LargeVector, sizeof(LargeVector)));
77   // Make sure we can encode and decode any byte.
78   std::vector<char> AllChars;
79   for (int Ch = INT8_MIN; Ch <= INT8_MAX; ++Ch)
80     AllChars.push_back(Ch);
81   Outputs.push_back(llvm::StringRef(AllChars.data(), AllChars.size()));
82 
83   for (const auto &Output : Outputs) {
84     // We trust that encoding is working after running the Base64Test::Base64()
85     // test function above, so we can use it to encode the string and verify we
86     // can decode it correctly.
87     auto Input = encodeBase64(Output);
88     TestBase64Decode(Input, Output);
89   }
90   struct ErrorInfo {
91     llvm::StringRef Input;
92     llvm::StringRef ErrorMessage;
93   };
94   std::vector<ErrorInfo> ErrorInfos = {
95       {"f", "Base64 encoded strings must be a multiple of 4 bytes in length"},
96       {"=abc", "Invalid Base64 character 0x3d at index 0"},
97       {"a=bc", "Invalid Base64 character 0x3d at index 1"},
98       {"ab=c", "Invalid Base64 character 0x3d at index 2"},
99       {"fun!", "Invalid Base64 character 0x21 at index 3"},
100   };
101 
102   for (const auto &EI : ErrorInfos)
103     TestBase64Decode(EI.Input, "", EI.ErrorMessage);
104 }
105