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. 23 void TestBase64(StringRef Input, StringRef Final) { 24 auto Res = encodeBase64(Input); 25 EXPECT_EQ(Res, Final); 26 } 27 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 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 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