11454c27bSserge-sans-paille //===- llvm/unittest/Support/Base64Test.cpp - Base64 tests
21454c27bSserge-sans-paille //--------------------===//
31454c27bSserge-sans-paille //
41454c27bSserge-sans-paille // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
51454c27bSserge-sans-paille // See https://llvm.org/LICENSE.txt for license information.
61454c27bSserge-sans-paille // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
71454c27bSserge-sans-paille //
81454c27bSserge-sans-paille //===----------------------------------------------------------------------===//
91454c27bSserge-sans-paille //
101454c27bSserge-sans-paille // This file implements unit tests for the Base64 functions.
111454c27bSserge-sans-paille //
121454c27bSserge-sans-paille //===----------------------------------------------------------------------===//
131454c27bSserge-sans-paille
141454c27bSserge-sans-paille #include "llvm/Support/Base64.h"
151454c27bSserge-sans-paille #include "llvm/ADT/StringRef.h"
16*ea9ac351SGreg Clayton #include "llvm/Testing/Support/Error.h"
171454c27bSserge-sans-paille #include "gtest/gtest.h"
181454c27bSserge-sans-paille
191454c27bSserge-sans-paille using namespace llvm;
201454c27bSserge-sans-paille
211454c27bSserge-sans-paille namespace {
221454c27bSserge-sans-paille /// Tests an arbitrary set of bytes passed as \p Input.
TestBase64(StringRef Input,StringRef Final)231454c27bSserge-sans-paille void TestBase64(StringRef Input, StringRef Final) {
241454c27bSserge-sans-paille auto Res = encodeBase64(Input);
251454c27bSserge-sans-paille EXPECT_EQ(Res, Final);
261454c27bSserge-sans-paille }
271454c27bSserge-sans-paille
TestBase64Decode(StringRef Input,StringRef Expected,StringRef ExpectedErrorMessage={})28*ea9ac351SGreg Clayton void TestBase64Decode(StringRef Input, StringRef Expected,
29*ea9ac351SGreg Clayton StringRef ExpectedErrorMessage = {}) {
30*ea9ac351SGreg Clayton std::vector<char> DecodedBytes;
31*ea9ac351SGreg Clayton if (ExpectedErrorMessage.empty()) {
32*ea9ac351SGreg Clayton ASSERT_THAT_ERROR(decodeBase64(Input, DecodedBytes), Succeeded());
33*ea9ac351SGreg Clayton EXPECT_EQ(llvm::ArrayRef<char>(DecodedBytes),
34*ea9ac351SGreg Clayton llvm::ArrayRef<char>(Expected.data(), Expected.size()));
35*ea9ac351SGreg Clayton } else {
36*ea9ac351SGreg Clayton ASSERT_THAT_ERROR(decodeBase64(Input, DecodedBytes),
37*ea9ac351SGreg Clayton FailedWithMessage(ExpectedErrorMessage));
38*ea9ac351SGreg Clayton }
39*ea9ac351SGreg Clayton }
40*ea9ac351SGreg Clayton
41*ea9ac351SGreg Clayton char NonPrintableVector[] = {0x00, 0x00, 0x00, 0x46,
42*ea9ac351SGreg Clayton 0x00, 0x08, (char)0xff, (char)0xee};
43*ea9ac351SGreg Clayton
44*ea9ac351SGreg Clayton char LargeVector[] = {0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63, 0x6b,
45*ea9ac351SGreg Clayton 0x20, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x20, 0x66, 0x6f,
46*ea9ac351SGreg Clayton 0x78, 0x20, 0x6a, 0x75, 0x6d, 0x70, 0x73, 0x20, 0x6f,
47*ea9ac351SGreg Clayton 0x76, 0x65, 0x72, 0x20, 0x31, 0x33, 0x20, 0x6c, 0x61,
48*ea9ac351SGreg Clayton 0x7a, 0x79, 0x20, 0x64, 0x6f, 0x67, 0x73, 0x2e};
49*ea9ac351SGreg Clayton
501454c27bSserge-sans-paille } // namespace
511454c27bSserge-sans-paille
TEST(Base64Test,Base64)521454c27bSserge-sans-paille TEST(Base64Test, Base64) {
531454c27bSserge-sans-paille // from: https://tools.ietf.org/html/rfc4648#section-10
541454c27bSserge-sans-paille TestBase64("", "");
551454c27bSserge-sans-paille TestBase64("f", "Zg==");
561454c27bSserge-sans-paille TestBase64("fo", "Zm8=");
571454c27bSserge-sans-paille TestBase64("foo", "Zm9v");
581454c27bSserge-sans-paille TestBase64("foob", "Zm9vYg==");
591454c27bSserge-sans-paille TestBase64("fooba", "Zm9vYmE=");
601454c27bSserge-sans-paille TestBase64("foobar", "Zm9vYmFy");
611454c27bSserge-sans-paille
621454c27bSserge-sans-paille // With non-printable values.
631454c27bSserge-sans-paille TestBase64({NonPrintableVector, sizeof(NonPrintableVector)}, "AAAARgAI/+4=");
641454c27bSserge-sans-paille
651454c27bSserge-sans-paille // Large test case
661454c27bSserge-sans-paille TestBase64({LargeVector, sizeof(LargeVector)},
671454c27bSserge-sans-paille "VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIDEzIGxhenkgZG9ncy4=");
681454c27bSserge-sans-paille }
69*ea9ac351SGreg Clayton
TEST(Base64Test,DecodeBase64)70*ea9ac351SGreg Clayton TEST(Base64Test, DecodeBase64) {
71*ea9ac351SGreg Clayton std::vector<llvm::StringRef> Outputs = {"", "f", "fo", "foo",
72*ea9ac351SGreg Clayton "foob", "fooba", "foobar"};
73*ea9ac351SGreg Clayton Outputs.push_back(
74*ea9ac351SGreg Clayton llvm::StringRef(NonPrintableVector, sizeof(NonPrintableVector)));
75*ea9ac351SGreg Clayton
76*ea9ac351SGreg Clayton Outputs.push_back(llvm::StringRef(LargeVector, sizeof(LargeVector)));
77*ea9ac351SGreg Clayton // Make sure we can encode and decode any byte.
78*ea9ac351SGreg Clayton std::vector<char> AllChars;
79*ea9ac351SGreg Clayton for (int Ch = INT8_MIN; Ch <= INT8_MAX; ++Ch)
80*ea9ac351SGreg Clayton AllChars.push_back(Ch);
81*ea9ac351SGreg Clayton Outputs.push_back(llvm::StringRef(AllChars.data(), AllChars.size()));
82*ea9ac351SGreg Clayton
83*ea9ac351SGreg Clayton for (const auto &Output : Outputs) {
84*ea9ac351SGreg Clayton // We trust that encoding is working after running the Base64Test::Base64()
85*ea9ac351SGreg Clayton // test function above, so we can use it to encode the string and verify we
86*ea9ac351SGreg Clayton // can decode it correctly.
87*ea9ac351SGreg Clayton auto Input = encodeBase64(Output);
88*ea9ac351SGreg Clayton TestBase64Decode(Input, Output);
89*ea9ac351SGreg Clayton }
90*ea9ac351SGreg Clayton struct ErrorInfo {
91*ea9ac351SGreg Clayton llvm::StringRef Input;
92*ea9ac351SGreg Clayton llvm::StringRef ErrorMessage;
93*ea9ac351SGreg Clayton };
94*ea9ac351SGreg Clayton std::vector<ErrorInfo> ErrorInfos = {
95*ea9ac351SGreg Clayton {"f", "Base64 encoded strings must be a multiple of 4 bytes in length"},
96*ea9ac351SGreg Clayton {"=abc", "Invalid Base64 character 0x3d at index 0"},
97*ea9ac351SGreg Clayton {"a=bc", "Invalid Base64 character 0x3d at index 1"},
98*ea9ac351SGreg Clayton {"ab=c", "Invalid Base64 character 0x3d at index 2"},
99*ea9ac351SGreg Clayton {"fun!", "Invalid Base64 character 0x21 at index 3"},
100*ea9ac351SGreg Clayton };
101*ea9ac351SGreg Clayton
102*ea9ac351SGreg Clayton for (const auto &EI : ErrorInfos)
103*ea9ac351SGreg Clayton TestBase64Decode(EI.Input, "", EI.ErrorMessage);
104*ea9ac351SGreg Clayton }
105