tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

escaping_test.cc (25186B)


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