blob: c2e7bc9332892ea78988875b6a3ad3f998723c09 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2015 The Chromium Authors
peter2b9a5dc62015-10-29 11:35:152// 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
Peter Kasting025a94252025-01-29 21:28:377#include <algorithm>
Helmut Januschka0fc785b2024-04-17 21:13:368#include <string_view>
9
Moe Ahmadib4410aa2023-06-26 19:09:2710#include "testing/gmock/include/gmock/gmock.h"
peter2b9a5dc62015-10-29 11:35:1511#include "testing/gtest/include/gtest/gtest.h"
12
Moe Ahmadib4410aa2023-06-26 19:09:2713using testing::ElementsAreArray;
14using testing::Optional;
15
peter2b9a5dc62015-10-29 11:35:1516namespace base {
17
18namespace {
19
Moe Ahmadib4410aa2023-06-26 19:09:2720TEST(Base64UrlTest, BinaryIncludePaddingPolicy) {
21 const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
22
23 std::string binary_encoded_with_padding;
24 Base64UrlEncode(kData, Base64UrlEncodePolicy::INCLUDE_PADDING,
25 &binary_encoded_with_padding);
26
Helmut Januschka0fc785b2024-04-17 21:13:3627 // Check that encoding the same binary data through the std::string_view
28 // interface gives the same result.
Moe Ahmadib4410aa2023-06-26 19:09:2729 std::string string_encoded_with_padding;
30 Base64UrlEncode(
Helmut Januschka0fc785b2024-04-17 21:13:3631 std::string_view(reinterpret_cast<const char*>(kData), sizeof(kData)),
Moe Ahmadib4410aa2023-06-26 19:09:2732 Base64UrlEncodePolicy::INCLUDE_PADDING, &string_encoded_with_padding);
33 EXPECT_EQ(binary_encoded_with_padding, string_encoded_with_padding);
34
35 // Check that decoding the result gives the same binary data.
36 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
37 Base64UrlDecodePolicy::REQUIRE_PADDING),
38 Optional(ElementsAreArray(kData)));
39
40 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
41 Base64UrlDecodePolicy::IGNORE_PADDING),
42 Optional(ElementsAreArray(kData)));
43
44 EXPECT_THAT(Base64UrlDecode(string_encoded_with_padding,
45 Base64UrlDecodePolicy::DISALLOW_PADDING),
Arthur Sonzognie5fff99c2024-02-21 15:58:2446 std::nullopt);
Moe Ahmadib4410aa2023-06-26 19:09:2747}
48
49TEST(Base64UrlTest, BinaryOmitPaddingPolicy) {
50 const uint8_t kData[] = {0x00, 0x01, 0xFE, 0xFF};
51
52 std::string binary_encoded_without_padding;
53 Base64UrlEncode(kData, Base64UrlEncodePolicy::OMIT_PADDING,
54 &binary_encoded_without_padding);
55
Helmut Januschka0fc785b2024-04-17 21:13:3656 // Check that encoding the same binary data through the std::string_view
57 // interface gives the same result.
Moe Ahmadib4410aa2023-06-26 19:09:2758 std::string string_encoded_without_padding;
59 Base64UrlEncode(
Helmut Januschka0fc785b2024-04-17 21:13:3660 std::string_view(reinterpret_cast<const char*>(kData), sizeof(kData)),
Moe Ahmadib4410aa2023-06-26 19:09:2761 Base64UrlEncodePolicy::OMIT_PADDING, &string_encoded_without_padding);
62 EXPECT_EQ(binary_encoded_without_padding, string_encoded_without_padding);
63
64 // Check that decoding the result gives the same binary data.
65 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
66 Base64UrlDecodePolicy::DISALLOW_PADDING),
67 Optional(ElementsAreArray(kData)));
68
69 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
70 Base64UrlDecodePolicy::IGNORE_PADDING),
71 Optional(ElementsAreArray(kData)));
72
73 EXPECT_THAT(Base64UrlDecode(string_encoded_without_padding,
74 Base64UrlDecodePolicy::REQUIRE_PADDING),
Arthur Sonzognie5fff99c2024-02-21 15:58:2475 std::nullopt);
Moe Ahmadib4410aa2023-06-26 19:09:2776}
77
peter2b9a5dc62015-10-29 11:35:1578TEST(Base64UrlTest, EncodeIncludePaddingPolicy) {
79 std::string output;
80 Base64UrlEncode("hello?world", Base64UrlEncodePolicy::INCLUDE_PADDING,
81 &output);
82
83 // Base64 version: aGVsbG8/d29ybGQ=
84 EXPECT_EQ("aGVsbG8_d29ybGQ=", output);
85
86 // Test for behavior for very short and empty strings.
87 Base64UrlEncode("??", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
88 EXPECT_EQ("Pz8=", output);
89
90 Base64UrlEncode("", Base64UrlEncodePolicy::INCLUDE_PADDING, &output);
91 EXPECT_EQ("", output);
92}
93
94TEST(Base64UrlTest, EncodeOmitPaddingPolicy) {
95 std::string output;
96 Base64UrlEncode("hello?world", Base64UrlEncodePolicy::OMIT_PADDING, &output);
97
98 // base64 version: aGVsbG8/d29ybGQ=
99 EXPECT_EQ("aGVsbG8_d29ybGQ", output);
100
101 // Test for behavior for very short and empty strings.
102 Base64UrlEncode("??", Base64UrlEncodePolicy::OMIT_PADDING, &output);
103 EXPECT_EQ("Pz8", output);
104
105 Base64UrlEncode("", Base64UrlEncodePolicy::OMIT_PADDING, &output);
106 EXPECT_EQ("", output);
107}
108
Nidhi Jaju95d13c22024-11-30 01:58:55109TEST(Base64UrlTest, EncodeInPlaceOmitPaddingPolicy) {
110 std::string input = "hello?world";
111 Base64UrlEncode(input, Base64UrlEncodePolicy::OMIT_PADDING, &input);
112 EXPECT_EQ("aGVsbG8_d29ybGQ", input);
113}
114
115TEST(Base64UrlTest, EncodeInPlaceIncludePaddingPolicy) {
116 std::string input = "hello?world";
117 Base64UrlEncode(input, Base64UrlEncodePolicy::INCLUDE_PADDING, &input);
118 EXPECT_EQ("aGVsbG8_d29ybGQ=", input);
119}
120
peter2b9a5dc62015-10-29 11:35:15121TEST(Base64UrlTest, DecodeRequirePaddingPolicy) {
122 std::string output;
Peter Kasting134ef9af2024-12-28 02:30:09123 ASSERT_TRUE(Base64UrlDecode(
124 "aGVsbG8_d29ybGQ=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
peter2b9a5dc62015-10-29 11:35:15125
126 EXPECT_EQ("hello?world", output);
127
128 ASSERT_FALSE(Base64UrlDecode(
129 "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
130
131 // Test for behavior for very short and empty strings.
132 ASSERT_TRUE(
133 Base64UrlDecode("Pz8=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
134 EXPECT_EQ("??", output);
135
136 ASSERT_TRUE(
137 Base64UrlDecode("", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
138 EXPECT_EQ("", output);
139}
140
141TEST(Base64UrlTest, DecodeIgnorePaddingPolicy) {
142 std::string output;
143 ASSERT_TRUE(Base64UrlDecode("aGVsbG8_d29ybGQ",
144 Base64UrlDecodePolicy::IGNORE_PADDING, &output));
145
146 EXPECT_EQ("hello?world", output);
147
148 // Including the padding is accepted as well.
Peter Kasting134ef9af2024-12-28 02:30:09149 ASSERT_TRUE(Base64UrlDecode(
150 "aGVsbG8_d29ybGQ=", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
peter2b9a5dc62015-10-29 11:35:15151
152 EXPECT_EQ("hello?world", output);
153}
154
Adam Langley4fd933ef2023-05-22 16:53:06155TEST(Base64UrlTest, DecodeIntoVector) {
156 ASSERT_FALSE(
157 Base64UrlDecode("invalid=", Base64UrlDecodePolicy::DISALLOW_PADDING));
158
159 static constexpr uint8_t kExpected[] = {'1', '2', '3', '4'};
Arthur Sonzognie5fff99c2024-02-21 15:58:24160 std::optional<std::vector<uint8_t>> result =
Adam Langley4fd933ef2023-05-22 16:53:06161 Base64UrlDecode("MTIzNA", Base64UrlDecodePolicy::DISALLOW_PADDING);
Peter Kasting025a94252025-01-29 21:28:37162 ASSERT_TRUE(std::ranges::equal(*result, kExpected));
Adam Langley4fd933ef2023-05-22 16:53:06163}
164
peter2b9a5dc62015-10-29 11:35:15165TEST(Base64UrlTest, DecodeDisallowPaddingPolicy) {
166 std::string output;
167 ASSERT_FALSE(Base64UrlDecode(
168 "aGVsbG8_d29ybGQ=", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
169
170 // The policy will allow the input when padding has been omitted.
171 ASSERT_TRUE(Base64UrlDecode(
172 "aGVsbG8_d29ybGQ", Base64UrlDecodePolicy::DISALLOW_PADDING, &output));
173
174 EXPECT_EQ("hello?world", output);
175}
176
177TEST(Base64UrlTest, DecodeDisallowsBase64Alphabet) {
178 std::string output;
179
180 // The "/" character is part of the conventional base64 alphabet, but has been
181 // substituted with "_" in the base64url alphabet.
182 ASSERT_FALSE(Base64UrlDecode(
183 "aGVsbG8/d29ybGQ=", Base64UrlDecodePolicy::REQUIRE_PADDING, &output));
184}
185
186TEST(Base64UrlTest, DecodeDisallowsPaddingOnly) {
187 std::string output;
188
Peter Kasting134ef9af2024-12-28 02:30:09189 ASSERT_FALSE(
190 Base64UrlDecode("=", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
191 ASSERT_FALSE(
192 Base64UrlDecode("==", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
193 ASSERT_FALSE(
194 Base64UrlDecode("===", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
195 ASSERT_FALSE(
196 Base64UrlDecode("====", Base64UrlDecodePolicy::IGNORE_PADDING, &output));
peter2b9a5dc62015-10-29 11:35:15197}
198
199} // namespace
200
201} // namespace base