xref: /aosp_15_r20/external/abseil-cpp/absl/strings/escaping_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/strings/escaping.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <array>
18*9356374aSAndroid Build Coastguard Worker #include <cstddef>
19*9356374aSAndroid Build Coastguard Worker #include <cstdio>
20*9356374aSAndroid Build Coastguard Worker #include <cstring>
21*9356374aSAndroid Build Coastguard Worker #include <initializer_list>
22*9356374aSAndroid Build Coastguard Worker #include <memory>
23*9356374aSAndroid Build Coastguard Worker #include <string>
24*9356374aSAndroid Build Coastguard Worker #include <vector>
25*9356374aSAndroid Build Coastguard Worker 
26*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/log/check.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
29*9356374aSAndroid Build Coastguard Worker 
30*9356374aSAndroid Build Coastguard Worker #include "absl/strings/internal/escaping_test_common.h"
31*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
32*9356374aSAndroid Build Coastguard Worker 
33*9356374aSAndroid Build Coastguard Worker namespace {
34*9356374aSAndroid Build Coastguard Worker 
35*9356374aSAndroid Build Coastguard Worker struct epair {
36*9356374aSAndroid Build Coastguard Worker   std::string escaped;
37*9356374aSAndroid Build Coastguard Worker   std::string unescaped;
38*9356374aSAndroid Build Coastguard Worker };
39*9356374aSAndroid Build Coastguard Worker 
TEST(CEscape,EscapeAndUnescape)40*9356374aSAndroid Build Coastguard Worker TEST(CEscape, EscapeAndUnescape) {
41*9356374aSAndroid Build Coastguard Worker   const std::string inputs[] = {
42*9356374aSAndroid Build Coastguard Worker       std::string("foo\nxx\r\b\0023"),
43*9356374aSAndroid Build Coastguard Worker       std::string(""),
44*9356374aSAndroid Build Coastguard Worker       std::string("abc"),
45*9356374aSAndroid Build Coastguard Worker       std::string("\1chad_rules"),
46*9356374aSAndroid Build Coastguard Worker       std::string("\1arnar_drools"),
47*9356374aSAndroid Build Coastguard Worker       std::string("xxxx\r\t'\"\\"),
48*9356374aSAndroid Build Coastguard Worker       std::string("\0xx\0", 4),
49*9356374aSAndroid Build Coastguard Worker       std::string("\x01\x31"),
50*9356374aSAndroid Build Coastguard Worker       std::string("abc\xb\x42\141bc"),
51*9356374aSAndroid Build Coastguard Worker       std::string("123\1\x31\x32\x33"),
52*9356374aSAndroid Build Coastguard Worker       std::string("\xc1\xca\x1b\x62\x19o\xcc\x04"),
53*9356374aSAndroid Build Coastguard Worker       std::string(
54*9356374aSAndroid Build Coastguard Worker           "\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name"),
55*9356374aSAndroid Build Coastguard Worker   };
56*9356374aSAndroid Build Coastguard Worker   // Do this twice, once for octal escapes and once for hex escapes.
57*9356374aSAndroid Build Coastguard Worker   for (int kind = 0; kind < 4; kind++) {
58*9356374aSAndroid Build Coastguard Worker     for (const std::string& original : inputs) {
59*9356374aSAndroid Build Coastguard Worker       std::string escaped;
60*9356374aSAndroid Build Coastguard Worker       switch (kind) {
61*9356374aSAndroid Build Coastguard Worker         case 0:
62*9356374aSAndroid Build Coastguard Worker           escaped = absl::CEscape(original);
63*9356374aSAndroid Build Coastguard Worker           break;
64*9356374aSAndroid Build Coastguard Worker         case 1:
65*9356374aSAndroid Build Coastguard Worker           escaped = absl::CHexEscape(original);
66*9356374aSAndroid Build Coastguard Worker           break;
67*9356374aSAndroid Build Coastguard Worker         case 2:
68*9356374aSAndroid Build Coastguard Worker           escaped = absl::Utf8SafeCEscape(original);
69*9356374aSAndroid Build Coastguard Worker           break;
70*9356374aSAndroid Build Coastguard Worker         case 3:
71*9356374aSAndroid Build Coastguard Worker           escaped = absl::Utf8SafeCHexEscape(original);
72*9356374aSAndroid Build Coastguard Worker           break;
73*9356374aSAndroid Build Coastguard Worker       }
74*9356374aSAndroid Build Coastguard Worker       std::string unescaped_str;
75*9356374aSAndroid Build Coastguard Worker       EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str));
76*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(unescaped_str, original);
77*9356374aSAndroid Build Coastguard Worker 
78*9356374aSAndroid Build Coastguard Worker       unescaped_str.erase();
79*9356374aSAndroid Build Coastguard Worker       std::string error;
80*9356374aSAndroid Build Coastguard Worker       EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str, &error));
81*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(error, "");
82*9356374aSAndroid Build Coastguard Worker 
83*9356374aSAndroid Build Coastguard Worker       // Check in-place unescaping
84*9356374aSAndroid Build Coastguard Worker       std::string s = escaped;
85*9356374aSAndroid Build Coastguard Worker       EXPECT_TRUE(absl::CUnescape(s, &s));
86*9356374aSAndroid Build Coastguard Worker       ASSERT_EQ(s, original);
87*9356374aSAndroid Build Coastguard Worker     }
88*9356374aSAndroid Build Coastguard Worker   }
89*9356374aSAndroid Build Coastguard Worker   // Check that all possible two character strings can be escaped then
90*9356374aSAndroid Build Coastguard Worker   // unescaped successfully.
91*9356374aSAndroid Build Coastguard Worker   for (int char0 = 0; char0 < 256; char0++) {
92*9356374aSAndroid Build Coastguard Worker     for (int char1 = 0; char1 < 256; char1++) {
93*9356374aSAndroid Build Coastguard Worker       char chars[2];
94*9356374aSAndroid Build Coastguard Worker       chars[0] = char0;
95*9356374aSAndroid Build Coastguard Worker       chars[1] = char1;
96*9356374aSAndroid Build Coastguard Worker       std::string s(chars, 2);
97*9356374aSAndroid Build Coastguard Worker       std::string escaped = absl::CHexEscape(s);
98*9356374aSAndroid Build Coastguard Worker       std::string unescaped;
99*9356374aSAndroid Build Coastguard Worker       EXPECT_TRUE(absl::CUnescape(escaped, &unescaped));
100*9356374aSAndroid Build Coastguard Worker       EXPECT_EQ(s, unescaped);
101*9356374aSAndroid Build Coastguard Worker     }
102*9356374aSAndroid Build Coastguard Worker   }
103*9356374aSAndroid Build Coastguard Worker }
104*9356374aSAndroid Build Coastguard Worker 
TEST(CEscape,BasicEscaping)105*9356374aSAndroid Build Coastguard Worker TEST(CEscape, BasicEscaping) {
106*9356374aSAndroid Build Coastguard Worker   epair oct_values[] = {
107*9356374aSAndroid Build Coastguard Worker       {"foo\\rbar\\nbaz\\t", "foo\rbar\nbaz\t"},
108*9356374aSAndroid Build Coastguard Worker       {"\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
109*9356374aSAndroid Build Coastguard Worker        "'full of \"sound\" and \"fury\"'"},
110*9356374aSAndroid Build Coastguard Worker       {"signi\\\\fying\\\\ nothing\\\\", "signi\\fying\\ nothing\\"},
111*9356374aSAndroid Build Coastguard Worker       {"\\010\\t\\n\\013\\014\\r", "\010\011\012\013\014\015"}
112*9356374aSAndroid Build Coastguard Worker   };
113*9356374aSAndroid Build Coastguard Worker   epair hex_values[] = {
114*9356374aSAndroid Build Coastguard Worker       {"ubik\\rubik\\nubik\\t", "ubik\rubik\nubik\t"},
115*9356374aSAndroid Build Coastguard Worker       {"I\\\'ve just seen a \\\"face\\\"",
116*9356374aSAndroid Build Coastguard Worker        "I've just seen a \"face\""},
117*9356374aSAndroid Build Coastguard Worker       {"hel\\\\ter\\\\skel\\\\ter\\\\", "hel\\ter\\skel\\ter\\"},
118*9356374aSAndroid Build Coastguard Worker       {"\\x08\\t\\n\\x0b\\x0c\\r", "\010\011\012\013\014\015"}
119*9356374aSAndroid Build Coastguard Worker   };
120*9356374aSAndroid Build Coastguard Worker   epair utf8_oct_values[] = {
121*9356374aSAndroid Build Coastguard Worker       {"\xe8\xb0\xb7\xe6\xad\x8c\\r\xe8\xb0\xb7\xe6\xad\x8c\\nbaz\\t",
122*9356374aSAndroid Build Coastguard Worker        "\xe8\xb0\xb7\xe6\xad\x8c\r\xe8\xb0\xb7\xe6\xad\x8c\nbaz\t"},
123*9356374aSAndroid Build Coastguard Worker       {"\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name",
124*9356374aSAndroid Build Coastguard Worker        "\"\xe8\xb0\xb7\xe6\xad\x8c\" is Google\'s Chinese name"},
125*9356374aSAndroid Build Coastguard Worker       {"\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\\\are\\\\Japanese\\\\chars\\\\",
126*9356374aSAndroid Build Coastguard Worker        "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\are\\Japanese\\chars\\"},
127*9356374aSAndroid Build Coastguard Worker       {"\xed\x81\xac\xeb\xa1\xac\\010\\t\\n\\013\\014\\r",
128*9356374aSAndroid Build Coastguard Worker        "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"}
129*9356374aSAndroid Build Coastguard Worker   };
130*9356374aSAndroid Build Coastguard Worker   epair utf8_hex_values[] = {
131*9356374aSAndroid Build Coastguard Worker       {"\x20\xe4\xbd\xa0\\t\xe5\xa5\xbd,\\r!\\n",
132*9356374aSAndroid Build Coastguard Worker        "\x20\xe4\xbd\xa0\t\xe5\xa5\xbd,\r!\n"},
133*9356374aSAndroid Build Coastguard Worker       {"\xe8\xa9\xa6\xe9\xa8\x93\\\' means \\\"test\\\"",
134*9356374aSAndroid Build Coastguard Worker        "\xe8\xa9\xa6\xe9\xa8\x93\' means \"test\""},
135*9356374aSAndroid Build Coastguard Worker       {"\\\\\xe6\x88\x91\\\\:\\\\\xe6\x9d\xa8\xe6\xac\xa2\\\\",
136*9356374aSAndroid Build Coastguard Worker        "\\\xe6\x88\x91\\:\\\xe6\x9d\xa8\xe6\xac\xa2\\"},
137*9356374aSAndroid Build Coastguard Worker       {"\xed\x81\xac\xeb\xa1\xac\\x08\\t\\n\\x0b\\x0c\\r",
138*9356374aSAndroid Build Coastguard Worker        "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"}
139*9356374aSAndroid Build Coastguard Worker   };
140*9356374aSAndroid Build Coastguard Worker 
141*9356374aSAndroid Build Coastguard Worker   for (const epair& val : oct_values) {
142*9356374aSAndroid Build Coastguard Worker     std::string escaped = absl::CEscape(val.unescaped);
143*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(escaped, val.escaped);
144*9356374aSAndroid Build Coastguard Worker   }
145*9356374aSAndroid Build Coastguard Worker   for (const epair& val : hex_values) {
146*9356374aSAndroid Build Coastguard Worker     std::string escaped = absl::CHexEscape(val.unescaped);
147*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(escaped, val.escaped);
148*9356374aSAndroid Build Coastguard Worker   }
149*9356374aSAndroid Build Coastguard Worker   for (const epair& val : utf8_oct_values) {
150*9356374aSAndroid Build Coastguard Worker     std::string escaped = absl::Utf8SafeCEscape(val.unescaped);
151*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(escaped, val.escaped);
152*9356374aSAndroid Build Coastguard Worker   }
153*9356374aSAndroid Build Coastguard Worker   for (const epair& val : utf8_hex_values) {
154*9356374aSAndroid Build Coastguard Worker     std::string escaped = absl::Utf8SafeCHexEscape(val.unescaped);
155*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(escaped, val.escaped);
156*9356374aSAndroid Build Coastguard Worker   }
157*9356374aSAndroid Build Coastguard Worker }
158*9356374aSAndroid Build Coastguard Worker 
TEST(Unescape,BasicFunction)159*9356374aSAndroid Build Coastguard Worker TEST(Unescape, BasicFunction) {
160*9356374aSAndroid Build Coastguard Worker   epair tests[] =
161*9356374aSAndroid Build Coastguard Worker     {{"", ""},
162*9356374aSAndroid Build Coastguard Worker      {"\\u0030", "0"},
163*9356374aSAndroid Build Coastguard Worker      {"\\u00A3", "\xC2\xA3"},
164*9356374aSAndroid Build Coastguard Worker      {"\\u22FD", "\xE2\x8B\xBD"},
165*9356374aSAndroid Build Coastguard Worker      {"\\U00010000", "\xF0\x90\x80\x80"},
166*9356374aSAndroid Build Coastguard Worker      {"\\U0010FFFD", "\xF4\x8F\xBF\xBD"}};
167*9356374aSAndroid Build Coastguard Worker   for (const epair& val : tests) {
168*9356374aSAndroid Build Coastguard Worker     std::string out;
169*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::CUnescape(val.escaped, &out));
170*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(out, val.unescaped);
171*9356374aSAndroid Build Coastguard Worker   }
172*9356374aSAndroid Build Coastguard Worker   std::string bad[] = {"\\u1",         // too short
173*9356374aSAndroid Build Coastguard Worker                        "\\U1",         // too short
174*9356374aSAndroid Build Coastguard Worker                        "\\Uffffff",    // exceeds 0x10ffff (largest Unicode)
175*9356374aSAndroid Build Coastguard Worker                        "\\U00110000",  // exceeds 0x10ffff (largest Unicode)
176*9356374aSAndroid Build Coastguard Worker                        "\\uD835",      // surrogate character (D800-DFFF)
177*9356374aSAndroid Build Coastguard Worker                        "\\U0000DD04",  // surrogate character (D800-DFFF)
178*9356374aSAndroid Build Coastguard Worker                        "\\777",        // exceeds 0xff
179*9356374aSAndroid Build Coastguard Worker                        "\\xABCD"};     // exceeds 0xff
180*9356374aSAndroid Build Coastguard Worker   for (const std::string& e : bad) {
181*9356374aSAndroid Build Coastguard Worker     std::string error;
182*9356374aSAndroid Build Coastguard Worker     std::string out;
183*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(absl::CUnescape(e, &out, &error));
184*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(error.empty());
185*9356374aSAndroid Build Coastguard Worker 
186*9356374aSAndroid Build Coastguard Worker     out.erase();
187*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(absl::CUnescape(e, &out));
188*9356374aSAndroid Build Coastguard Worker   }
189*9356374aSAndroid Build Coastguard Worker }
190*9356374aSAndroid Build Coastguard Worker 
191*9356374aSAndroid Build Coastguard Worker class CUnescapeTest : public testing::Test {
192*9356374aSAndroid Build Coastguard Worker  protected:
193*9356374aSAndroid Build Coastguard Worker   static const char kStringWithMultipleOctalNulls[];
194*9356374aSAndroid Build Coastguard Worker   static const char kStringWithMultipleHexNulls[];
195*9356374aSAndroid Build Coastguard Worker   static const char kStringWithMultipleUnicodeNulls[];
196*9356374aSAndroid Build Coastguard Worker 
197*9356374aSAndroid Build Coastguard Worker   std::string result_string_;
198*9356374aSAndroid Build Coastguard Worker };
199*9356374aSAndroid Build Coastguard Worker 
200*9356374aSAndroid Build Coastguard Worker const char CUnescapeTest::kStringWithMultipleOctalNulls[] =
201*9356374aSAndroid Build Coastguard Worker     "\\0\\n"    // null escape \0 plus newline
202*9356374aSAndroid Build Coastguard Worker     "0\\n"      // just a number 0 (not a null escape) plus newline
203*9356374aSAndroid Build Coastguard Worker     "\\00\\12"  // null escape \00 plus octal newline code
204*9356374aSAndroid Build Coastguard Worker     "\\000";    // null escape \000
205*9356374aSAndroid Build Coastguard Worker 
206*9356374aSAndroid Build Coastguard Worker // This has the same ingredients as kStringWithMultipleOctalNulls
207*9356374aSAndroid Build Coastguard Worker // but with \x hex escapes instead of octal escapes.
208*9356374aSAndroid Build Coastguard Worker const char CUnescapeTest::kStringWithMultipleHexNulls[] =
209*9356374aSAndroid Build Coastguard Worker     "\\x0\\n"
210*9356374aSAndroid Build Coastguard Worker     "0\\n"
211*9356374aSAndroid Build Coastguard Worker     "\\x00\\xa"
212*9356374aSAndroid Build Coastguard Worker     "\\x000";
213*9356374aSAndroid Build Coastguard Worker 
214*9356374aSAndroid Build Coastguard Worker const char CUnescapeTest::kStringWithMultipleUnicodeNulls[] =
215*9356374aSAndroid Build Coastguard Worker     "\\u0000\\n"    // short-form (4-digit) null escape plus newline
216*9356374aSAndroid Build Coastguard Worker     "0\\n"          // just a number 0 (not a null escape) plus newline
217*9356374aSAndroid Build Coastguard Worker     "\\U00000000";  // long-form (8-digit) null escape
218*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes1CharOctalNull)219*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes1CharOctalNull) {
220*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\0";
221*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
222*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
223*9356374aSAndroid Build Coastguard Worker }
224*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes2CharOctalNull)225*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes2CharOctalNull) {
226*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\00";
227*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
228*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
229*9356374aSAndroid Build Coastguard Worker }
230*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes3CharOctalNull)231*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes3CharOctalNull) {
232*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\000";
233*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
234*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
235*9356374aSAndroid Build Coastguard Worker }
236*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes1CharHexNull)237*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes1CharHexNull) {
238*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\x0";
239*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
240*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
241*9356374aSAndroid Build Coastguard Worker }
242*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes2CharHexNull)243*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes2CharHexNull) {
244*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\x00";
245*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
246*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
247*9356374aSAndroid Build Coastguard Worker }
248*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes3CharHexNull)249*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes3CharHexNull) {
250*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\x000";
251*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
252*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
253*9356374aSAndroid Build Coastguard Worker }
254*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes4CharUnicodeNull)255*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes4CharUnicodeNull) {
256*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\u0000";
257*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
258*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
259*9356374aSAndroid Build Coastguard Worker }
260*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,Unescapes8CharUnicodeNull)261*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, Unescapes8CharUnicodeNull) {
262*9356374aSAndroid Build Coastguard Worker   std::string original_string = "\\U00000000";
263*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
264*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0", 1), result_string_);
265*9356374aSAndroid Build Coastguard Worker }
266*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,UnescapesMultipleOctalNulls)267*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, UnescapesMultipleOctalNulls) {
268*9356374aSAndroid Build Coastguard Worker   std::string original_string(kStringWithMultipleOctalNulls);
269*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
270*9356374aSAndroid Build Coastguard Worker   // All escapes, including newlines and null escapes, should have been
271*9356374aSAndroid Build Coastguard Worker   // converted to the equivalent characters.
272*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0\n"
273*9356374aSAndroid Build Coastguard Worker                         "0\n"
274*9356374aSAndroid Build Coastguard Worker                         "\0\n"
275*9356374aSAndroid Build Coastguard Worker                         "\0",
276*9356374aSAndroid Build Coastguard Worker                         7),
277*9356374aSAndroid Build Coastguard Worker             result_string_);
278*9356374aSAndroid Build Coastguard Worker }
279*9356374aSAndroid Build Coastguard Worker 
280*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,UnescapesMultipleHexNulls)281*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, UnescapesMultipleHexNulls) {
282*9356374aSAndroid Build Coastguard Worker   std::string original_string(kStringWithMultipleHexNulls);
283*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
284*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0\n"
285*9356374aSAndroid Build Coastguard Worker                         "0\n"
286*9356374aSAndroid Build Coastguard Worker                         "\0\n"
287*9356374aSAndroid Build Coastguard Worker                         "\0",
288*9356374aSAndroid Build Coastguard Worker                         7),
289*9356374aSAndroid Build Coastguard Worker             result_string_);
290*9356374aSAndroid Build Coastguard Worker }
291*9356374aSAndroid Build Coastguard Worker 
TEST_F(CUnescapeTest,UnescapesMultipleUnicodeNulls)292*9356374aSAndroid Build Coastguard Worker TEST_F(CUnescapeTest, UnescapesMultipleUnicodeNulls) {
293*9356374aSAndroid Build Coastguard Worker   std::string original_string(kStringWithMultipleUnicodeNulls);
294*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));
295*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(std::string("\0\n"
296*9356374aSAndroid Build Coastguard Worker                         "0\n"
297*9356374aSAndroid Build Coastguard Worker                         "\0",
298*9356374aSAndroid Build Coastguard Worker                         5),
299*9356374aSAndroid Build Coastguard Worker             result_string_);
300*9356374aSAndroid Build Coastguard Worker }
301*9356374aSAndroid Build Coastguard Worker 
302*9356374aSAndroid Build Coastguard Worker static struct {
303*9356374aSAndroid Build Coastguard Worker   absl::string_view plaintext;
304*9356374aSAndroid Build Coastguard Worker   absl::string_view cyphertext;
305*9356374aSAndroid Build Coastguard Worker } const base64_tests[] = {
306*9356374aSAndroid Build Coastguard Worker     // Empty string.
307*9356374aSAndroid Build Coastguard Worker     {{"", 0}, {"", 0}},
308*9356374aSAndroid Build Coastguard Worker     {{nullptr, 0},
309*9356374aSAndroid Build Coastguard Worker      {"", 0}},  // if length is zero, plaintext ptr must be ignored!
310*9356374aSAndroid Build Coastguard Worker 
311*9356374aSAndroid Build Coastguard Worker     // Basic bit patterns;
312*9356374aSAndroid Build Coastguard Worker     // values obtained with "echo -n '...' | uuencode -m test"
313*9356374aSAndroid Build Coastguard Worker 
314*9356374aSAndroid Build Coastguard Worker     {{"\000", 1}, "AA=="},
315*9356374aSAndroid Build Coastguard Worker     {{"\001", 1}, "AQ=="},
316*9356374aSAndroid Build Coastguard Worker     {{"\002", 1}, "Ag=="},
317*9356374aSAndroid Build Coastguard Worker     {{"\004", 1}, "BA=="},
318*9356374aSAndroid Build Coastguard Worker     {{"\010", 1}, "CA=="},
319*9356374aSAndroid Build Coastguard Worker     {{"\020", 1}, "EA=="},
320*9356374aSAndroid Build Coastguard Worker     {{"\040", 1}, "IA=="},
321*9356374aSAndroid Build Coastguard Worker     {{"\100", 1}, "QA=="},
322*9356374aSAndroid Build Coastguard Worker     {{"\200", 1}, "gA=="},
323*9356374aSAndroid Build Coastguard Worker 
324*9356374aSAndroid Build Coastguard Worker     {{"\377", 1}, "/w=="},
325*9356374aSAndroid Build Coastguard Worker     {{"\376", 1}, "/g=="},
326*9356374aSAndroid Build Coastguard Worker     {{"\375", 1}, "/Q=="},
327*9356374aSAndroid Build Coastguard Worker     {{"\373", 1}, "+w=="},
328*9356374aSAndroid Build Coastguard Worker     {{"\367", 1}, "9w=="},
329*9356374aSAndroid Build Coastguard Worker     {{"\357", 1}, "7w=="},
330*9356374aSAndroid Build Coastguard Worker     {{"\337", 1}, "3w=="},
331*9356374aSAndroid Build Coastguard Worker     {{"\277", 1}, "vw=="},
332*9356374aSAndroid Build Coastguard Worker     {{"\177", 1}, "fw=="},
333*9356374aSAndroid Build Coastguard Worker     {{"\000\000", 2}, "AAA="},
334*9356374aSAndroid Build Coastguard Worker     {{"\000\001", 2}, "AAE="},
335*9356374aSAndroid Build Coastguard Worker     {{"\000\002", 2}, "AAI="},
336*9356374aSAndroid Build Coastguard Worker     {{"\000\004", 2}, "AAQ="},
337*9356374aSAndroid Build Coastguard Worker     {{"\000\010", 2}, "AAg="},
338*9356374aSAndroid Build Coastguard Worker     {{"\000\020", 2}, "ABA="},
339*9356374aSAndroid Build Coastguard Worker     {{"\000\040", 2}, "ACA="},
340*9356374aSAndroid Build Coastguard Worker     {{"\000\100", 2}, "AEA="},
341*9356374aSAndroid Build Coastguard Worker     {{"\000\200", 2}, "AIA="},
342*9356374aSAndroid Build Coastguard Worker     {{"\001\000", 2}, "AQA="},
343*9356374aSAndroid Build Coastguard Worker     {{"\002\000", 2}, "AgA="},
344*9356374aSAndroid Build Coastguard Worker     {{"\004\000", 2}, "BAA="},
345*9356374aSAndroid Build Coastguard Worker     {{"\010\000", 2}, "CAA="},
346*9356374aSAndroid Build Coastguard Worker     {{"\020\000", 2}, "EAA="},
347*9356374aSAndroid Build Coastguard Worker     {{"\040\000", 2}, "IAA="},
348*9356374aSAndroid Build Coastguard Worker     {{"\100\000", 2}, "QAA="},
349*9356374aSAndroid Build Coastguard Worker     {{"\200\000", 2}, "gAA="},
350*9356374aSAndroid Build Coastguard Worker 
351*9356374aSAndroid Build Coastguard Worker     {{"\377\377", 2}, "//8="},
352*9356374aSAndroid Build Coastguard Worker     {{"\377\376", 2}, "//4="},
353*9356374aSAndroid Build Coastguard Worker     {{"\377\375", 2}, "//0="},
354*9356374aSAndroid Build Coastguard Worker     {{"\377\373", 2}, "//s="},
355*9356374aSAndroid Build Coastguard Worker     {{"\377\367", 2}, "//c="},
356*9356374aSAndroid Build Coastguard Worker     {{"\377\357", 2}, "/+8="},
357*9356374aSAndroid Build Coastguard Worker     {{"\377\337", 2}, "/98="},
358*9356374aSAndroid Build Coastguard Worker     {{"\377\277", 2}, "/78="},
359*9356374aSAndroid Build Coastguard Worker     {{"\377\177", 2}, "/38="},
360*9356374aSAndroid Build Coastguard Worker     {{"\376\377", 2}, "/v8="},
361*9356374aSAndroid Build Coastguard Worker     {{"\375\377", 2}, "/f8="},
362*9356374aSAndroid Build Coastguard Worker     {{"\373\377", 2}, "+/8="},
363*9356374aSAndroid Build Coastguard Worker     {{"\367\377", 2}, "9/8="},
364*9356374aSAndroid Build Coastguard Worker     {{"\357\377", 2}, "7/8="},
365*9356374aSAndroid Build Coastguard Worker     {{"\337\377", 2}, "3/8="},
366*9356374aSAndroid Build Coastguard Worker     {{"\277\377", 2}, "v/8="},
367*9356374aSAndroid Build Coastguard Worker     {{"\177\377", 2}, "f/8="},
368*9356374aSAndroid Build Coastguard Worker 
369*9356374aSAndroid Build Coastguard Worker     {{"\000\000\000", 3}, "AAAA"},
370*9356374aSAndroid Build Coastguard Worker     {{"\000\000\001", 3}, "AAAB"},
371*9356374aSAndroid Build Coastguard Worker     {{"\000\000\002", 3}, "AAAC"},
372*9356374aSAndroid Build Coastguard Worker     {{"\000\000\004", 3}, "AAAE"},
373*9356374aSAndroid Build Coastguard Worker     {{"\000\000\010", 3}, "AAAI"},
374*9356374aSAndroid Build Coastguard Worker     {{"\000\000\020", 3}, "AAAQ"},
375*9356374aSAndroid Build Coastguard Worker     {{"\000\000\040", 3}, "AAAg"},
376*9356374aSAndroid Build Coastguard Worker     {{"\000\000\100", 3}, "AABA"},
377*9356374aSAndroid Build Coastguard Worker     {{"\000\000\200", 3}, "AACA"},
378*9356374aSAndroid Build Coastguard Worker     {{"\000\001\000", 3}, "AAEA"},
379*9356374aSAndroid Build Coastguard Worker     {{"\000\002\000", 3}, "AAIA"},
380*9356374aSAndroid Build Coastguard Worker     {{"\000\004\000", 3}, "AAQA"},
381*9356374aSAndroid Build Coastguard Worker     {{"\000\010\000", 3}, "AAgA"},
382*9356374aSAndroid Build Coastguard Worker     {{"\000\020\000", 3}, "ABAA"},
383*9356374aSAndroid Build Coastguard Worker     {{"\000\040\000", 3}, "ACAA"},
384*9356374aSAndroid Build Coastguard Worker     {{"\000\100\000", 3}, "AEAA"},
385*9356374aSAndroid Build Coastguard Worker     {{"\000\200\000", 3}, "AIAA"},
386*9356374aSAndroid Build Coastguard Worker     {{"\001\000\000", 3}, "AQAA"},
387*9356374aSAndroid Build Coastguard Worker     {{"\002\000\000", 3}, "AgAA"},
388*9356374aSAndroid Build Coastguard Worker     {{"\004\000\000", 3}, "BAAA"},
389*9356374aSAndroid Build Coastguard Worker     {{"\010\000\000", 3}, "CAAA"},
390*9356374aSAndroid Build Coastguard Worker     {{"\020\000\000", 3}, "EAAA"},
391*9356374aSAndroid Build Coastguard Worker     {{"\040\000\000", 3}, "IAAA"},
392*9356374aSAndroid Build Coastguard Worker     {{"\100\000\000", 3}, "QAAA"},
393*9356374aSAndroid Build Coastguard Worker     {{"\200\000\000", 3}, "gAAA"},
394*9356374aSAndroid Build Coastguard Worker 
395*9356374aSAndroid Build Coastguard Worker     {{"\377\377\377", 3}, "////"},
396*9356374aSAndroid Build Coastguard Worker     {{"\377\377\376", 3}, "///+"},
397*9356374aSAndroid Build Coastguard Worker     {{"\377\377\375", 3}, "///9"},
398*9356374aSAndroid Build Coastguard Worker     {{"\377\377\373", 3}, "///7"},
399*9356374aSAndroid Build Coastguard Worker     {{"\377\377\367", 3}, "///3"},
400*9356374aSAndroid Build Coastguard Worker     {{"\377\377\357", 3}, "///v"},
401*9356374aSAndroid Build Coastguard Worker     {{"\377\377\337", 3}, "///f"},
402*9356374aSAndroid Build Coastguard Worker     {{"\377\377\277", 3}, "//+/"},
403*9356374aSAndroid Build Coastguard Worker     {{"\377\377\177", 3}, "//9/"},
404*9356374aSAndroid Build Coastguard Worker     {{"\377\376\377", 3}, "//7/"},
405*9356374aSAndroid Build Coastguard Worker     {{"\377\375\377", 3}, "//3/"},
406*9356374aSAndroid Build Coastguard Worker     {{"\377\373\377", 3}, "//v/"},
407*9356374aSAndroid Build Coastguard Worker     {{"\377\367\377", 3}, "//f/"},
408*9356374aSAndroid Build Coastguard Worker     {{"\377\357\377", 3}, "/+//"},
409*9356374aSAndroid Build Coastguard Worker     {{"\377\337\377", 3}, "/9//"},
410*9356374aSAndroid Build Coastguard Worker     {{"\377\277\377", 3}, "/7//"},
411*9356374aSAndroid Build Coastguard Worker     {{"\377\177\377", 3}, "/3//"},
412*9356374aSAndroid Build Coastguard Worker     {{"\376\377\377", 3}, "/v//"},
413*9356374aSAndroid Build Coastguard Worker     {{"\375\377\377", 3}, "/f//"},
414*9356374aSAndroid Build Coastguard Worker     {{"\373\377\377", 3}, "+///"},
415*9356374aSAndroid Build Coastguard Worker     {{"\367\377\377", 3}, "9///"},
416*9356374aSAndroid Build Coastguard Worker     {{"\357\377\377", 3}, "7///"},
417*9356374aSAndroid Build Coastguard Worker     {{"\337\377\377", 3}, "3///"},
418*9356374aSAndroid Build Coastguard Worker     {{"\277\377\377", 3}, "v///"},
419*9356374aSAndroid Build Coastguard Worker     {{"\177\377\377", 3}, "f///"},
420*9356374aSAndroid Build Coastguard Worker 
421*9356374aSAndroid Build Coastguard Worker     // Random numbers: values obtained with
422*9356374aSAndroid Build Coastguard Worker     //
423*9356374aSAndroid Build Coastguard Worker     //  #! /bin/bash
424*9356374aSAndroid Build Coastguard Worker     //  dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random
425*9356374aSAndroid Build Coastguard Worker     //  od -N $1 -t o1 /tmp/bar.random
426*9356374aSAndroid Build Coastguard Worker     //  uuencode -m test < /tmp/bar.random
427*9356374aSAndroid Build Coastguard Worker     //
428*9356374aSAndroid Build Coastguard Worker     // where $1 is the number of bytes (2, 3)
429*9356374aSAndroid Build Coastguard Worker 
430*9356374aSAndroid Build Coastguard Worker     {{"\243\361", 2}, "o/E="},
431*9356374aSAndroid Build Coastguard Worker     {{"\024\167", 2}, "FHc="},
432*9356374aSAndroid Build Coastguard Worker     {{"\313\252", 2}, "y6o="},
433*9356374aSAndroid Build Coastguard Worker     {{"\046\041", 2}, "JiE="},
434*9356374aSAndroid Build Coastguard Worker     {{"\145\236", 2}, "ZZ4="},
435*9356374aSAndroid Build Coastguard Worker     {{"\254\325", 2}, "rNU="},
436*9356374aSAndroid Build Coastguard Worker     {{"\061\330", 2}, "Mdg="},
437*9356374aSAndroid Build Coastguard Worker     {{"\245\032", 2}, "pRo="},
438*9356374aSAndroid Build Coastguard Worker     {{"\006\000", 2}, "BgA="},
439*9356374aSAndroid Build Coastguard Worker     {{"\375\131", 2}, "/Vk="},
440*9356374aSAndroid Build Coastguard Worker     {{"\303\210", 2}, "w4g="},
441*9356374aSAndroid Build Coastguard Worker     {{"\040\037", 2}, "IB8="},
442*9356374aSAndroid Build Coastguard Worker     {{"\261\372", 2}, "sfo="},
443*9356374aSAndroid Build Coastguard Worker     {{"\335\014", 2}, "3Qw="},
444*9356374aSAndroid Build Coastguard Worker     {{"\233\217", 2}, "m48="},
445*9356374aSAndroid Build Coastguard Worker     {{"\373\056", 2}, "+y4="},
446*9356374aSAndroid Build Coastguard Worker     {{"\247\232", 2}, "p5o="},
447*9356374aSAndroid Build Coastguard Worker     {{"\107\053", 2}, "Rys="},
448*9356374aSAndroid Build Coastguard Worker     {{"\204\077", 2}, "hD8="},
449*9356374aSAndroid Build Coastguard Worker     {{"\276\211", 2}, "vok="},
450*9356374aSAndroid Build Coastguard Worker     {{"\313\110", 2}, "y0g="},
451*9356374aSAndroid Build Coastguard Worker     {{"\363\376", 2}, "8/4="},
452*9356374aSAndroid Build Coastguard Worker     {{"\251\234", 2}, "qZw="},
453*9356374aSAndroid Build Coastguard Worker     {{"\103\262", 2}, "Q7I="},
454*9356374aSAndroid Build Coastguard Worker     {{"\142\312", 2}, "Yso="},
455*9356374aSAndroid Build Coastguard Worker     {{"\067\211", 2}, "N4k="},
456*9356374aSAndroid Build Coastguard Worker     {{"\220\001", 2}, "kAE="},
457*9356374aSAndroid Build Coastguard Worker     {{"\152\240", 2}, "aqA="},
458*9356374aSAndroid Build Coastguard Worker     {{"\367\061", 2}, "9zE="},
459*9356374aSAndroid Build Coastguard Worker     {{"\133\255", 2}, "W60="},
460*9356374aSAndroid Build Coastguard Worker     {{"\176\035", 2}, "fh0="},
461*9356374aSAndroid Build Coastguard Worker     {{"\032\231", 2}, "Gpk="},
462*9356374aSAndroid Build Coastguard Worker 
463*9356374aSAndroid Build Coastguard Worker     {{"\013\007\144", 3}, "Cwdk"},
464*9356374aSAndroid Build Coastguard Worker     {{"\030\112\106", 3}, "GEpG"},
465*9356374aSAndroid Build Coastguard Worker     {{"\047\325\046", 3}, "J9Um"},
466*9356374aSAndroid Build Coastguard Worker     {{"\310\160\022", 3}, "yHAS"},
467*9356374aSAndroid Build Coastguard Worker     {{"\131\100\237", 3}, "WUCf"},
468*9356374aSAndroid Build Coastguard Worker     {{"\064\342\134", 3}, "NOJc"},
469*9356374aSAndroid Build Coastguard Worker     {{"\010\177\004", 3}, "CH8E"},
470*9356374aSAndroid Build Coastguard Worker     {{"\345\147\205", 3}, "5WeF"},
471*9356374aSAndroid Build Coastguard Worker     {{"\300\343\360", 3}, "wOPw"},
472*9356374aSAndroid Build Coastguard Worker     {{"\061\240\201", 3}, "MaCB"},
473*9356374aSAndroid Build Coastguard Worker     {{"\225\333\044", 3}, "ldsk"},
474*9356374aSAndroid Build Coastguard Worker     {{"\215\137\352", 3}, "jV/q"},
475*9356374aSAndroid Build Coastguard Worker     {{"\371\147\160", 3}, "+Wdw"},
476*9356374aSAndroid Build Coastguard Worker     {{"\030\320\051", 3}, "GNAp"},
477*9356374aSAndroid Build Coastguard Worker     {{"\044\174\241", 3}, "JHyh"},
478*9356374aSAndroid Build Coastguard Worker     {{"\260\127\037", 3}, "sFcf"},
479*9356374aSAndroid Build Coastguard Worker     {{"\111\045\033", 3}, "SSUb"},
480*9356374aSAndroid Build Coastguard Worker     {{"\202\114\107", 3}, "gkxH"},
481*9356374aSAndroid Build Coastguard Worker     {{"\057\371\042", 3}, "L/ki"},
482*9356374aSAndroid Build Coastguard Worker     {{"\223\247\244", 3}, "k6ek"},
483*9356374aSAndroid Build Coastguard Worker     {{"\047\216\144", 3}, "J45k"},
484*9356374aSAndroid Build Coastguard Worker     {{"\203\070\327", 3}, "gzjX"},
485*9356374aSAndroid Build Coastguard Worker     {{"\247\140\072", 3}, "p2A6"},
486*9356374aSAndroid Build Coastguard Worker     {{"\124\115\116", 3}, "VE1O"},
487*9356374aSAndroid Build Coastguard Worker     {{"\157\162\050", 3}, "b3Io"},
488*9356374aSAndroid Build Coastguard Worker     {{"\357\223\004", 3}, "75ME"},
489*9356374aSAndroid Build Coastguard Worker     {{"\052\117\156", 3}, "Kk9u"},
490*9356374aSAndroid Build Coastguard Worker     {{"\347\154\000", 3}, "52wA"},
491*9356374aSAndroid Build Coastguard Worker     {{"\303\012\142", 3}, "wwpi"},
492*9356374aSAndroid Build Coastguard Worker     {{"\060\035\362", 3}, "MB3y"},
493*9356374aSAndroid Build Coastguard Worker     {{"\130\226\361", 3}, "WJbx"},
494*9356374aSAndroid Build Coastguard Worker     {{"\173\013\071", 3}, "ews5"},
495*9356374aSAndroid Build Coastguard Worker     {{"\336\004\027", 3}, "3gQX"},
496*9356374aSAndroid Build Coastguard Worker     {{"\357\366\234", 3}, "7/ac"},
497*9356374aSAndroid Build Coastguard Worker     {{"\353\304\111", 3}, "68RJ"},
498*9356374aSAndroid Build Coastguard Worker     {{"\024\264\131", 3}, "FLRZ"},
499*9356374aSAndroid Build Coastguard Worker     {{"\075\114\251", 3}, "PUyp"},
500*9356374aSAndroid Build Coastguard Worker     {{"\315\031\225", 3}, "zRmV"},
501*9356374aSAndroid Build Coastguard Worker     {{"\154\201\276", 3}, "bIG+"},
502*9356374aSAndroid Build Coastguard Worker     {{"\200\066\072", 3}, "gDY6"},
503*9356374aSAndroid Build Coastguard Worker     {{"\142\350\267", 3}, "Yui3"},
504*9356374aSAndroid Build Coastguard Worker     {{"\033\000\166", 3}, "GwB2"},
505*9356374aSAndroid Build Coastguard Worker     {{"\210\055\077", 3}, "iC0/"},
506*9356374aSAndroid Build Coastguard Worker     {{"\341\037\124", 3}, "4R9U"},
507*9356374aSAndroid Build Coastguard Worker     {{"\161\103\152", 3}, "cUNq"},
508*9356374aSAndroid Build Coastguard Worker     {{"\270\142\131", 3}, "uGJZ"},
509*9356374aSAndroid Build Coastguard Worker     {{"\337\076\074", 3}, "3z48"},
510*9356374aSAndroid Build Coastguard Worker     {{"\375\106\362", 3}, "/Uby"},
511*9356374aSAndroid Build Coastguard Worker     {{"\227\301\127", 3}, "l8FX"},
512*9356374aSAndroid Build Coastguard Worker     {{"\340\002\234", 3}, "4AKc"},
513*9356374aSAndroid Build Coastguard Worker     {{"\121\064\033", 3}, "UTQb"},
514*9356374aSAndroid Build Coastguard Worker     {{"\157\134\143", 3}, "b1xj"},
515*9356374aSAndroid Build Coastguard Worker     {{"\247\055\327", 3}, "py3X"},
516*9356374aSAndroid Build Coastguard Worker     {{"\340\142\005", 3}, "4GIF"},
517*9356374aSAndroid Build Coastguard Worker     {{"\060\260\143", 3}, "MLBj"},
518*9356374aSAndroid Build Coastguard Worker     {{"\075\203\170", 3}, "PYN4"},
519*9356374aSAndroid Build Coastguard Worker     {{"\143\160\016", 3}, "Y3AO"},
520*9356374aSAndroid Build Coastguard Worker     {{"\313\013\063", 3}, "ywsz"},
521*9356374aSAndroid Build Coastguard Worker     {{"\174\236\135", 3}, "fJ5d"},
522*9356374aSAndroid Build Coastguard Worker     {{"\103\047\026", 3}, "QycW"},
523*9356374aSAndroid Build Coastguard Worker     {{"\365\005\343", 3}, "9QXj"},
524*9356374aSAndroid Build Coastguard Worker     {{"\271\160\223", 3}, "uXCT"},
525*9356374aSAndroid Build Coastguard Worker     {{"\362\255\172", 3}, "8q16"},
526*9356374aSAndroid Build Coastguard Worker     {{"\113\012\015", 3}, "SwoN"},
527*9356374aSAndroid Build Coastguard Worker 
528*9356374aSAndroid Build Coastguard Worker     // various lengths, generated by this python script:
529*9356374aSAndroid Build Coastguard Worker     //
530*9356374aSAndroid Build Coastguard Worker     // from std::string import lowercase as lc
531*9356374aSAndroid Build Coastguard Worker     // for i in range(27):
532*9356374aSAndroid Build Coastguard Worker     //   print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i),
533*9356374aSAndroid Build Coastguard Worker     //                                     lc[:i].encode('base64').strip())
534*9356374aSAndroid Build Coastguard Worker 
535*9356374aSAndroid Build Coastguard Worker     {{"", 0}, {"", 0}},
536*9356374aSAndroid Build Coastguard Worker     {"a", "YQ=="},
537*9356374aSAndroid Build Coastguard Worker     {"ab", "YWI="},
538*9356374aSAndroid Build Coastguard Worker     {"abc", "YWJj"},
539*9356374aSAndroid Build Coastguard Worker     {"abcd", "YWJjZA=="},
540*9356374aSAndroid Build Coastguard Worker     {"abcde", "YWJjZGU="},
541*9356374aSAndroid Build Coastguard Worker     {"abcdef", "YWJjZGVm"},
542*9356374aSAndroid Build Coastguard Worker     {"abcdefg", "YWJjZGVmZw=="},
543*9356374aSAndroid Build Coastguard Worker     {"abcdefgh", "YWJjZGVmZ2g="},
544*9356374aSAndroid Build Coastguard Worker     {"abcdefghi", "YWJjZGVmZ2hp"},
545*9356374aSAndroid Build Coastguard Worker     {"abcdefghij", "YWJjZGVmZ2hpag=="},
546*9356374aSAndroid Build Coastguard Worker     {"abcdefghijk", "YWJjZGVmZ2hpams="},
547*9356374aSAndroid Build Coastguard Worker     {"abcdefghijkl", "YWJjZGVmZ2hpamts"},
548*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklm", "YWJjZGVmZ2hpamtsbQ=="},
549*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmn", "YWJjZGVmZ2hpamtsbW4="},
550*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmno", "YWJjZGVmZ2hpamtsbW5v"},
551*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnop", "YWJjZGVmZ2hpamtsbW5vcA=="},
552*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopq", "YWJjZGVmZ2hpamtsbW5vcHE="},
553*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqr", "YWJjZGVmZ2hpamtsbW5vcHFy"},
554*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrs", "YWJjZGVmZ2hpamtsbW5vcHFycw=="},
555*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrst", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q="},
556*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstu", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1"},
557*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstuv", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg=="},
558*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstuvw", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc="},
559*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstuvwx", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"},
560*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ=="},
561*9356374aSAndroid Build Coastguard Worker     {"abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="},
562*9356374aSAndroid Build Coastguard Worker };
563*9356374aSAndroid Build Coastguard Worker 
564*9356374aSAndroid Build Coastguard Worker template <typename StringType>
TestEscapeAndUnescape()565*9356374aSAndroid Build Coastguard Worker void TestEscapeAndUnescape() {
566*9356374aSAndroid Build Coastguard Worker   // Check the short strings; this tests the math (and boundaries)
567*9356374aSAndroid Build Coastguard Worker   for (const auto& tc : base64_tests) {
568*9356374aSAndroid Build Coastguard Worker     // Test plain base64.
569*9356374aSAndroid Build Coastguard Worker     StringType encoded("this junk should be ignored");
570*9356374aSAndroid Build Coastguard Worker     absl::Base64Escape(tc.plaintext, &encoded);
571*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(encoded, tc.cyphertext);
572*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(absl::Base64Escape(tc.plaintext), tc.cyphertext);
573*9356374aSAndroid Build Coastguard Worker 
574*9356374aSAndroid Build Coastguard Worker     StringType decoded("this junk should be ignored");
575*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::Base64Unescape(encoded, &decoded));
576*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(decoded, tc.plaintext);
577*9356374aSAndroid Build Coastguard Worker 
578*9356374aSAndroid Build Coastguard Worker     StringType websafe_with_padding(tc.cyphertext);
579*9356374aSAndroid Build Coastguard Worker     for (unsigned int c = 0; c < websafe_with_padding.size(); ++c) {
580*9356374aSAndroid Build Coastguard Worker       if ('+' == websafe_with_padding[c]) websafe_with_padding[c] = '-';
581*9356374aSAndroid Build Coastguard Worker       if ('/' == websafe_with_padding[c]) websafe_with_padding[c] = '_';
582*9356374aSAndroid Build Coastguard Worker       // Intentionally keeping padding aka '='.
583*9356374aSAndroid Build Coastguard Worker     }
584*9356374aSAndroid Build Coastguard Worker 
585*9356374aSAndroid Build Coastguard Worker     // Test plain websafe (aka without padding).
586*9356374aSAndroid Build Coastguard Worker     StringType websafe(websafe_with_padding);
587*9356374aSAndroid Build Coastguard Worker     for (unsigned int c = 0; c < websafe.size(); ++c) {
588*9356374aSAndroid Build Coastguard Worker       if ('=' == websafe[c]) {
589*9356374aSAndroid Build Coastguard Worker         websafe.resize(c);
590*9356374aSAndroid Build Coastguard Worker         break;
591*9356374aSAndroid Build Coastguard Worker       }
592*9356374aSAndroid Build Coastguard Worker     }
593*9356374aSAndroid Build Coastguard Worker     encoded = "this junk should be ignored";
594*9356374aSAndroid Build Coastguard Worker     absl::WebSafeBase64Escape(tc.plaintext, &encoded);
595*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(encoded, websafe);
596*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), websafe);
597*9356374aSAndroid Build Coastguard Worker 
598*9356374aSAndroid Build Coastguard Worker     decoded = "this junk should be ignored";
599*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::WebSafeBase64Unescape(websafe, &decoded));
600*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(decoded, tc.plaintext);
601*9356374aSAndroid Build Coastguard Worker   }
602*9356374aSAndroid Build Coastguard Worker 
603*9356374aSAndroid Build Coastguard Worker   // Now try the long strings, this tests the streaming
604*9356374aSAndroid Build Coastguard Worker   for (const auto& tc : absl::strings_internal::base64_strings()) {
605*9356374aSAndroid Build Coastguard Worker     StringType buffer;
606*9356374aSAndroid Build Coastguard Worker     absl::WebSafeBase64Escape(tc.plaintext, &buffer);
607*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(tc.cyphertext, buffer);
608*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(absl::WebSafeBase64Escape(tc.plaintext), tc.cyphertext);
609*9356374aSAndroid Build Coastguard Worker   }
610*9356374aSAndroid Build Coastguard Worker 
611*9356374aSAndroid Build Coastguard Worker   // Verify the behavior when decoding bad data
612*9356374aSAndroid Build Coastguard Worker   {
613*9356374aSAndroid Build Coastguard Worker     absl::string_view data_set[] = {"ab-/", absl::string_view("\0bcd", 4),
614*9356374aSAndroid Build Coastguard Worker                                     absl::string_view("abc.\0", 5)};
615*9356374aSAndroid Build Coastguard Worker     for (absl::string_view bad_data : data_set) {
616*9356374aSAndroid Build Coastguard Worker       StringType buf;
617*9356374aSAndroid Build Coastguard Worker       EXPECT_FALSE(absl::Base64Unescape(bad_data, &buf));
618*9356374aSAndroid Build Coastguard Worker       EXPECT_FALSE(absl::WebSafeBase64Unescape(bad_data, &buf));
619*9356374aSAndroid Build Coastguard Worker       EXPECT_TRUE(buf.empty());
620*9356374aSAndroid Build Coastguard Worker     }
621*9356374aSAndroid Build Coastguard Worker   }
622*9356374aSAndroid Build Coastguard Worker }
623*9356374aSAndroid Build Coastguard Worker 
TEST(Base64,EscapeAndUnescape)624*9356374aSAndroid Build Coastguard Worker TEST(Base64, EscapeAndUnescape) {
625*9356374aSAndroid Build Coastguard Worker   TestEscapeAndUnescape<std::string>();
626*9356374aSAndroid Build Coastguard Worker }
627*9356374aSAndroid Build Coastguard Worker 
TEST(Base64,Padding)628*9356374aSAndroid Build Coastguard Worker TEST(Base64, Padding) {
629*9356374aSAndroid Build Coastguard Worker   // Padding is optional.
630*9356374aSAndroid Build Coastguard Worker   // '.' is an acceptable padding character, just like '='.
631*9356374aSAndroid Build Coastguard Worker   std::initializer_list<absl::string_view> good_padding = {
632*9356374aSAndroid Build Coastguard Worker     "YQ",
633*9356374aSAndroid Build Coastguard Worker     "YQ==",
634*9356374aSAndroid Build Coastguard Worker     "YQ=.",
635*9356374aSAndroid Build Coastguard Worker     "YQ.=",
636*9356374aSAndroid Build Coastguard Worker     "YQ..",
637*9356374aSAndroid Build Coastguard Worker   };
638*9356374aSAndroid Build Coastguard Worker   for (absl::string_view b64 : good_padding) {
639*9356374aSAndroid Build Coastguard Worker     std::string decoded;
640*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::Base64Unescape(b64, &decoded));
641*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(decoded, "a");
642*9356374aSAndroid Build Coastguard Worker     std::string websafe_decoded;
643*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(absl::WebSafeBase64Unescape(b64, &websafe_decoded));
644*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(websafe_decoded, "a");
645*9356374aSAndroid Build Coastguard Worker   }
646*9356374aSAndroid Build Coastguard Worker   std::initializer_list<absl::string_view> bad_padding = {
647*9356374aSAndroid Build Coastguard Worker     "YQ=",
648*9356374aSAndroid Build Coastguard Worker     "YQ.",
649*9356374aSAndroid Build Coastguard Worker     "YQ===",
650*9356374aSAndroid Build Coastguard Worker     "YQ==.",
651*9356374aSAndroid Build Coastguard Worker     "YQ=.=",
652*9356374aSAndroid Build Coastguard Worker     "YQ=..",
653*9356374aSAndroid Build Coastguard Worker     "YQ.==",
654*9356374aSAndroid Build Coastguard Worker     "YQ.=.",
655*9356374aSAndroid Build Coastguard Worker     "YQ..=",
656*9356374aSAndroid Build Coastguard Worker     "YQ...",
657*9356374aSAndroid Build Coastguard Worker     "YQ====",
658*9356374aSAndroid Build Coastguard Worker     "YQ....",
659*9356374aSAndroid Build Coastguard Worker     "YQ=====",
660*9356374aSAndroid Build Coastguard Worker     "YQ.....",
661*9356374aSAndroid Build Coastguard Worker   };
662*9356374aSAndroid Build Coastguard Worker   for (absl::string_view b64 : bad_padding) {
663*9356374aSAndroid Build Coastguard Worker     std::string decoded;
664*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(absl::Base64Unescape(b64, &decoded));
665*9356374aSAndroid Build Coastguard Worker     std::string websafe_decoded;
666*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(absl::WebSafeBase64Unescape(b64, &websafe_decoded));
667*9356374aSAndroid Build Coastguard Worker   }
668*9356374aSAndroid Build Coastguard Worker }
669*9356374aSAndroid Build Coastguard Worker 
TEST(Base64,DISABLED_HugeData)670*9356374aSAndroid Build Coastguard Worker TEST(Base64, DISABLED_HugeData) {
671*9356374aSAndroid Build Coastguard Worker   const size_t kSize = size_t(3) * 1000 * 1000 * 1000;
672*9356374aSAndroid Build Coastguard Worker   static_assert(kSize % 3 == 0, "kSize must be divisible by 3");
673*9356374aSAndroid Build Coastguard Worker   const std::string huge(kSize, 'x');
674*9356374aSAndroid Build Coastguard Worker 
675*9356374aSAndroid Build Coastguard Worker   std::string escaped;
676*9356374aSAndroid Build Coastguard Worker   absl::Base64Escape(huge, &escaped);
677*9356374aSAndroid Build Coastguard Worker 
678*9356374aSAndroid Build Coastguard Worker   // Generates the string that should match a base64 encoded "xxx..." string.
679*9356374aSAndroid Build Coastguard Worker   // "xxx" in base64 is "eHh4".
680*9356374aSAndroid Build Coastguard Worker   std::string expected_encoding;
681*9356374aSAndroid Build Coastguard Worker   expected_encoding.reserve(kSize / 3 * 4);
682*9356374aSAndroid Build Coastguard Worker   for (size_t i = 0; i < kSize / 3; ++i) {
683*9356374aSAndroid Build Coastguard Worker     expected_encoding.append("eHh4");
684*9356374aSAndroid Build Coastguard Worker   }
685*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected_encoding, escaped);
686*9356374aSAndroid Build Coastguard Worker 
687*9356374aSAndroid Build Coastguard Worker   std::string unescaped;
688*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::Base64Unescape(escaped, &unescaped));
689*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(huge, unescaped);
690*9356374aSAndroid Build Coastguard Worker }
691*9356374aSAndroid Build Coastguard Worker 
TEST(Escaping,HexStringToBytesBackToHex)692*9356374aSAndroid Build Coastguard Worker TEST(Escaping, HexStringToBytesBackToHex) {
693*9356374aSAndroid Build Coastguard Worker   std::string bytes, hex;
694*9356374aSAndroid Build Coastguard Worker 
695*9356374aSAndroid Build Coastguard Worker   constexpr absl::string_view kTestHexLower =  "1c2f0032f40123456789abcdef";
696*9356374aSAndroid Build Coastguard Worker   constexpr absl::string_view kTestHexUpper =  "1C2F0032F40123456789ABCDEF";
697*9356374aSAndroid Build Coastguard Worker   constexpr absl::string_view kTestBytes = absl::string_view(
698*9356374aSAndroid Build Coastguard Worker       "\x1c\x2f\x00\x32\xf4\x01\x23\x45\x67\x89\xab\xcd\xef", 13);
699*9356374aSAndroid Build Coastguard Worker 
700*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::HexStringToBytes(kTestHexLower, &bytes));
701*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes, kTestBytes);
702*9356374aSAndroid Build Coastguard Worker 
703*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::HexStringToBytes(kTestHexUpper, &bytes));
704*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes, kTestBytes);
705*9356374aSAndroid Build Coastguard Worker 
706*9356374aSAndroid Build Coastguard Worker   hex = absl::BytesToHexString(kTestBytes);
707*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(hex, kTestHexLower);
708*9356374aSAndroid Build Coastguard Worker 
709*9356374aSAndroid Build Coastguard Worker   // Same buffer.
710*9356374aSAndroid Build Coastguard Worker   // We do not care if this works since we do not promise it in the contract.
711*9356374aSAndroid Build Coastguard Worker   // The purpose of this test is to to see if the program will crash or if
712*9356374aSAndroid Build Coastguard Worker   // sanitizers will catch anything.
713*9356374aSAndroid Build Coastguard Worker   bytes = std::string(kTestHexUpper);
714*9356374aSAndroid Build Coastguard Worker   (void)absl::HexStringToBytes(bytes, &bytes);
715*9356374aSAndroid Build Coastguard Worker 
716*9356374aSAndroid Build Coastguard Worker   // Length not a multiple of two.
717*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::HexStringToBytes("1c2f003", &bytes));
718*9356374aSAndroid Build Coastguard Worker 
719*9356374aSAndroid Build Coastguard Worker   // Not hex.
720*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(absl::HexStringToBytes("1c2f00ft", &bytes));
721*9356374aSAndroid Build Coastguard Worker 
722*9356374aSAndroid Build Coastguard Worker   // Empty input.
723*9356374aSAndroid Build Coastguard Worker   bytes = "abc";
724*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(absl::HexStringToBytes("", &bytes));
725*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ("", bytes);  // Results in empty output.
726*9356374aSAndroid Build Coastguard Worker }
727*9356374aSAndroid Build Coastguard Worker 
TEST(HexAndBack,HexStringToBytes_and_BytesToHexString)728*9356374aSAndroid Build Coastguard Worker TEST(HexAndBack, HexStringToBytes_and_BytesToHexString) {
729*9356374aSAndroid Build Coastguard Worker   std::string hex_mixed = "0123456789abcdefABCDEF";
730*9356374aSAndroid Build Coastguard Worker   std::string bytes_expected = "\x01\x23\x45\x67\x89\xab\xcd\xef\xAB\xCD\xEF";
731*9356374aSAndroid Build Coastguard Worker   std::string hex_only_lower = "0123456789abcdefabcdef";
732*9356374aSAndroid Build Coastguard Worker 
733*9356374aSAndroid Build Coastguard Worker   std::string bytes_result = absl::HexStringToBytes(hex_mixed);
734*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_expected, bytes_result);
735*9356374aSAndroid Build Coastguard Worker 
736*9356374aSAndroid Build Coastguard Worker   std::string prefix_valid = hex_mixed + "?";
737*9356374aSAndroid Build Coastguard Worker   std::string prefix_valid_result = absl::HexStringToBytes(
738*9356374aSAndroid Build Coastguard Worker       absl::string_view(prefix_valid.data(), prefix_valid.size() - 1));
739*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_expected, prefix_valid_result);
740*9356374aSAndroid Build Coastguard Worker 
741*9356374aSAndroid Build Coastguard Worker   std::string infix_valid = "?" + hex_mixed + "???";
742*9356374aSAndroid Build Coastguard Worker   std::string infix_valid_result = absl::HexStringToBytes(
743*9356374aSAndroid Build Coastguard Worker       absl::string_view(infix_valid.data() + 1, hex_mixed.size()));
744*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(bytes_expected, infix_valid_result);
745*9356374aSAndroid Build Coastguard Worker 
746*9356374aSAndroid Build Coastguard Worker   std::string hex_result = absl::BytesToHexString(bytes_expected);
747*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(hex_only_lower, hex_result);
748*9356374aSAndroid Build Coastguard Worker }
749*9356374aSAndroid Build Coastguard Worker 
750*9356374aSAndroid Build Coastguard Worker }  // namespace
751