• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "base/base64url.h"
6 
7 #include "base/ranges/algorithm.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 using testing::ElementsAreArray;
12 using testing::Optional;
13 
14 namespace base {
15 
16 namespace {
17 
TEST(Base64UrlTest,BinaryIncludePaddingPolicy)18 TEST(Base64UrlTest, BinaryIncludePaddingPolicy) {
19   const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
20 
21   std::string binary_encoded_with_padding;
22   Base64UrlEncode(kData, Base64UrlEncodePolicy::INCLUDE_PADDING,
23                   &binary_encoded_with_padding);
24 
25   // Check that encoding the same binary data through the StringPiece interface
26   // gives the same result.
27   std::string string_encoded_with_padding;
28   Base64UrlEncode(
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);
32 
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)));
37 
38   EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
39                               Base64UrlDecodePolicy::IGNORE_PADDING),
40               Optional(ElementsAreArray(kData)));
41 
42   EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
43                               Base64UrlDecodePolicy::DISALLOW_PADDING),
44               absl::nullopt);
45 }
46 
TEST(Base64UrlTest,BinaryOmitPaddingPolicy)47 TEST(Base64UrlTest, BinaryOmitPaddingPolicy) {
48   const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
49 
50   std::string binary_encoded_without_padding;
51   Base64UrlEncode(kData, Base64UrlEncodePolicy::OMIT_PADDING,
52                   &binary_encoded_without_padding);
53 
54   // Check that encoding the same binary data through the StringPiece interface
55   // gives the same result.
56   std::string string_encoded_without_padding;
57   Base64UrlEncode(
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);
61 
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)));
66 
67   EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
68                               Base64UrlDecodePolicy::IGNORE_PADDING),
69               Optional(ElementsAreArray(kData)));
70 
71   EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
72                               Base64UrlDecodePolicy::REQUIRE_PADDING),
73               absl::nullopt);
74 }
75 
TEST(Base64UrlTest,EncodeIncludePaddingPolicy)76 TEST(Base64UrlTest, EncodeIncludePaddingPolicy) {
77   std::string output;
78   Base64UrlEncode("hello?world", Base64UrlEncodePolicy::INCLUDE_PADDING,
79                   &output);
80 
81   // Base64 version: aGVsbG8/d29ybGQ=
82   EXPECT_EQ("aGVsbG8_d29ybGQ=", output);
83 
84   // Test for behavior for very short and empty strings.
85   Base64UrlEncode("??", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
86   EXPECT_EQ("Pz8=", output);
87 
88   Base64UrlEncode("", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
89   EXPECT_EQ("", output);
90 }
91 
TEST(Base64UrlTest,EncodeOmitPaddingPolicy)92 TEST(Base64UrlTest, EncodeOmitPaddingPolicy) {
93   std::string output;
94   Base64UrlEncode("hello?world", Base64UrlEncodePolicy::OMIT_PADDING, &output);
95 
96   // base64 version: aGVsbG8/d29ybGQ=
97   EXPECT_EQ("aGVsbG8_d29ybGQ", output);
98 
99   // Test for behavior for very short and empty strings.
100   Base64UrlEncode("??", Base64UrlEncodePolicy::OMIT_PADDING, &output);
101   EXPECT_EQ("Pz8", output);
102 
103   Base64UrlEncode("", Base64UrlEncodePolicy::OMIT_PADDING, &output);
104   EXPECT_EQ("", output);
105 }
106 
TEST(Base64UrlTest,DecodeRequirePaddingPolicy)107 TEST(Base64UrlTest, DecodeRequirePaddingPolicy) {
108   std::string output;
109   ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ=",
110                               Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
111 
112   EXPECT_EQ("hello?world", output);
113 
114   ASSERT_FALSE(Base64UrlDecode(
115       "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
116 
117   // Test for behavior for very short and empty strings.
118   ASSERT_TRUE(
119       Base64UrlDecode("Pz8=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
120   EXPECT_EQ("??", output);
121 
122   ASSERT_TRUE(
123       Base64UrlDecode("", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
124   EXPECT_EQ("", output);
125 }
126 
TEST(Base64UrlTest,DecodeIgnorePaddingPolicy)127 TEST(Base64UrlTest, DecodeIgnorePaddingPolicy) {
128   std::string output;
129   ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ",
130                               Base64UrlDecodePolicy::IGNORE_PADDING, &output));
131 
132   EXPECT_EQ("hello?world", output);
133 
134   // Including the padding is accepted as well.
135   ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ=",
136                               Base64UrlDecodePolicy::IGNORE_PADDING, &output));
137 
138   EXPECT_EQ("hello?world", output);
139 }
140 
TEST(Base64UrlTest,DecodeIntoVector)141 TEST(Base64UrlTest, DecodeIntoVector) {
142   ASSERT_FALSE(
143       Base64UrlDecode("invalid=", Base64UrlDecodePolicy::DISALLOW_PADDING));
144 
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));
149 }
150 
TEST(Base64UrlTest,DecodeDisallowPaddingPolicy)151 TEST(Base64UrlTest, DecodeDisallowPaddingPolicy) {
152   std::string output;
153   ASSERT_FALSE(Base64UrlDecode(
154       "aGVsbG8_d29ybGQ=", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
155 
156   // The policy will allow the input when padding has been omitted.
157   ASSERT_TRUE(Base64UrlDecode(
158       "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
159 
160   EXPECT_EQ("hello?world", output);
161 }
162 
TEST(Base64UrlTest,DecodeDisallowsBase64Alphabet)163 TEST(Base64UrlTest, DecodeDisallowsBase64Alphabet) {
164   std::string output;
165 
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));
170 }
171 
TEST(Base64UrlTest,DecodeDisallowsPaddingOnly)172 TEST(Base64UrlTest, DecodeDisallowsPaddingOnly) {
173   std::string output;
174 
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));
183 }
184 
185 }  // namespace
186 
187 }  // namespace base
188