1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/base64url.h"
7 #include "base/ranges/algorithm.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using testing::ElementsAreArray;
12 using testing::Optional;
18 TEST(Base64UrlTest, BinaryIncludePaddingPolicy) {
19 const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
21 std::string binary_encoded_with_padding;
22 Base64UrlEncode(kData, Base64UrlEncodePolicy::INCLUDE_PADDING,
23 &binary_encoded_with_padding);
25 // Check that encoding the same binary data through the StringPiece interface
26 // gives the same result.
27 std::string string_encoded_with_padding;
29 StringPiece(reinterpret_cast<const char*>(kData), sizeof(kData)),
30 Base64UrlEncodePolicy::INCLUDE_PADDING, &string_encoded_with_padding);
31 EXPECT_EQ(binary_encoded_with_padding, string_encoded_with_padding);
33 // Check that decoding the result gives the same binary data.
34 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
35 Base64UrlDecodePolicy::REQUIRE_PADDING),
36 Optional(ElementsAreArray(kData)));
38 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
39 Base64UrlDecodePolicy::IGNORE_PADDING),
40 Optional(ElementsAreArray(kData)));
42 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
43 Base64UrlDecodePolicy::DISALLOW_PADDING),
47 TEST(Base64UrlTest, BinaryOmitPaddingPolicy) {
48 const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
50 std::string binary_encoded_without_padding;
51 Base64UrlEncode(kData, Base64UrlEncodePolicy::OMIT_PADDING,
52 &binary_encoded_without_padding);
54 // Check that encoding the same binary data through the StringPiece interface
55 // gives the same result.
56 std::string string_encoded_without_padding;
58 StringPiece(reinterpret_cast<const char*>(kData), sizeof(kData)),
59 Base64UrlEncodePolicy::OMIT_PADDING, &string_encoded_without_padding);
60 EXPECT_EQ(binary_encoded_without_padding, string_encoded_without_padding);
62 // Check that decoding the result gives the same binary data.
63 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
64 Base64UrlDecodePolicy::DISALLOW_PADDING),
65 Optional(ElementsAreArray(kData)));
67 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
68 Base64UrlDecodePolicy::IGNORE_PADDING),
69 Optional(ElementsAreArray(kData)));
71 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
72 Base64UrlDecodePolicy::REQUIRE_PADDING),
76 TEST(Base64UrlTest, EncodeIncludePaddingPolicy) {
78 Base64UrlEncode("hello?world", Base64UrlEncodePolicy::INCLUDE_PADDING,
81 // Base64 version: aGVsbG8/d29ybGQ=
82 EXPECT_EQ("aGVsbG8_d29ybGQ=", output);
84 // Test for behavior for very short and empty strings.
85 Base64UrlEncode("??", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
86 EXPECT_EQ("Pz8=", output);
88 Base64UrlEncode("", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
89 EXPECT_EQ("", output);
92 TEST(Base64UrlTest, EncodeOmitPaddingPolicy) {
94 Base64UrlEncode("hello?world", Base64UrlEncodePolicy::OMIT_PADDING, &output);
96 // base64 version: aGVsbG8/d29ybGQ=
97 EXPECT_EQ("aGVsbG8_d29ybGQ", output);
99 // Test for behavior for very short and empty strings.
100 Base64UrlEncode("??", Base64UrlEncodePolicy::OMIT_PADDING, &output);
101 EXPECT_EQ("Pz8", output);
103 Base64UrlEncode("", Base64UrlEncodePolicy::OMIT_PADDING, &output);
104 EXPECT_EQ("", output);
107 TEST(Base64UrlTest, DecodeRequirePaddingPolicy) {
109 ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ=",
110 Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
112 EXPECT_EQ("hello?world", output);
114 ASSERT_FALSE(Base64UrlDecode(
115 "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
117 // Test for behavior for very short and empty strings.
119 Base64UrlDecode("Pz8=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
120 EXPECT_EQ("??", output);
123 Base64UrlDecode("", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
124 EXPECT_EQ("", output);
127 TEST(Base64UrlTest, DecodeIgnorePaddingPolicy) {
129 ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ",
130 Base64UrlDecodePolicy::IGNORE_PADDING, &output));
132 EXPECT_EQ("hello?world", output);
134 // Including the padding is accepted as well.
135 ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ=",
136 Base64UrlDecodePolicy::IGNORE_PADDING, &output));
138 EXPECT_EQ("hello?world", output);
141 TEST(Base64UrlTest, DecodeIntoVector) {
143 Base64UrlDecode("invalid=", Base64UrlDecodePolicy::DISALLOW_PADDING));
145 static constexpr uint8_t kExpected[] = {'1', '2', '3', '4'};
146 absl::optional<std::vector<uint8_t>> result =
147 Base64UrlDecode("MTIzNA", Base64UrlDecodePolicy::DISALLOW_PADDING);
148 ASSERT_TRUE(ranges::equal(*result, kExpected));
151 TEST(Base64UrlTest, DecodeDisallowPaddingPolicy) {
153 ASSERT_FALSE(Base64UrlDecode(
154 "aGVsbG8_d29ybGQ=", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
156 // The policy will allow the input when padding has been omitted.
157 ASSERT_TRUE(Base64UrlDecode(
158 "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
160 EXPECT_EQ("hello?world", output);
163 TEST(Base64UrlTest, DecodeDisallowsBase64Alphabet) {
166 // The "/" character is part of the conventional base64 alphabet, but has been
167 // substituted with "_" in the base64url alphabet.
168 ASSERT_FALSE(Base64UrlDecode(
169 "aGVsbG8/d29ybGQ=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
172 TEST(Base64UrlTest, DecodeDisallowsPaddingOnly) {
175 ASSERT_FALSE(Base64UrlDecode(
176 "=", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
177 ASSERT_FALSE(Base64UrlDecode(
178 "==", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
179 ASSERT_FALSE(Base64UrlDecode(
180 "===", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
181 ASSERT_FALSE(Base64UrlDecode(
182 "====", Base64UrlDecodePolicy::IGNORE_PADDING, &output));