| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638 | // Copyright 2017 The Abseil Authors.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////      http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include "absl/strings/escaping.h"#include <array>#include <cstdio>#include <cstring>#include <memory>#include <vector>#include "gmock/gmock.h"#include "gtest/gtest.h"#include "absl/container/fixed_array.h"#include "absl/strings/str_cat.h"#include "absl/strings/internal/escaping_test_common.inc"namespace {struct epair {  std::string escaped;  std::string unescaped;};TEST(CEscape, EscapeAndUnescape) {  const std::string inputs[] = {    std::string("foo\nxx\r\b\0023"),    std::string(""),    std::string("abc"),    std::string("\1chad_rules"),    std::string("\1arnar_drools"),    std::string("xxxx\r\t'\"\\"),    std::string("\0xx\0", 4),    std::string("\x01\x31"),    std::string("abc\xb\x42\141bc"),    std::string("123\1\x31\x32\x33"),    std::string("\xc1\xca\x1b\x62\x19o\xcc\x04"),    std::string("\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name"),  };  // Do this twice, once for octal escapes and once for hex escapes.  for (int kind = 0; kind < 4; kind++) {    for (const std::string& original : inputs) {      std::string escaped;      switch (kind) {        case 0:          escaped = absl::CEscape(original);          break;        case 1:          escaped = absl::CHexEscape(original);          break;        case 2:          escaped = absl::Utf8SafeCEscape(original);          break;        case 3:          escaped = absl::Utf8SafeCHexEscape(original);          break;      }      std::string unescaped_str;      EXPECT_TRUE(absl::CUnescape(escaped, &unescaped_str));      EXPECT_EQ(unescaped_str, original);      // Check in-place unescaping      std::string s = escaped;      EXPECT_TRUE(absl::CUnescape(s, &s));      ASSERT_EQ(s, original);    }  }  // Check that all possible two character strings can be escaped then  // unescaped successfully.  for (int char0 = 0; char0 < 256; char0++) {    for (int char1 = 0; char1 < 256; char1++) {      char chars[2];      chars[0] = char0;      chars[1] = char1;      std::string s(chars, 2);      std::string escaped = absl::CHexEscape(s);      std::string unescaped;      EXPECT_TRUE(absl::CUnescape(escaped, &unescaped));      EXPECT_EQ(s, unescaped);    }  }}TEST(CEscape, BasicEscaping) {  epair oct_values[] = {      {"foo\\rbar\\nbaz\\t", "foo\rbar\nbaz\t"},      {"\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",       "'full of \"sound\" and \"fury\"'"},      {"signi\\\\fying\\\\ nothing\\\\", "signi\\fying\\ nothing\\"},      {"\\010\\t\\n\\013\\014\\r", "\010\011\012\013\014\015"}  };  epair hex_values[] = {      {"ubik\\rubik\\nubik\\t", "ubik\rubik\nubik\t"},      {"I\\\'ve just seen a \\\"face\\\"",       "I've just seen a \"face\""},      {"hel\\\\ter\\\\skel\\\\ter\\\\", "hel\\ter\\skel\\ter\\"},      {"\\x08\\t\\n\\x0b\\x0c\\r", "\010\011\012\013\014\015"}  };  epair utf8_oct_values[] = {      {"\xe8\xb0\xb7\xe6\xad\x8c\\r\xe8\xb0\xb7\xe6\xad\x8c\\nbaz\\t",       "\xe8\xb0\xb7\xe6\xad\x8c\r\xe8\xb0\xb7\xe6\xad\x8c\nbaz\t"},      {"\\\"\xe8\xb0\xb7\xe6\xad\x8c\\\" is Google\\\'s Chinese name",       "\"\xe8\xb0\xb7\xe6\xad\x8c\" is Google\'s Chinese name"},      {"\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\\\are\\\\Japanese\\\\chars\\\\",       "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\xab\\are\\Japanese\\chars\\"},      {"\xed\x81\xac\xeb\xa1\xac\\010\\t\\n\\013\\014\\r",       "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"}  };  epair utf8_hex_values[] = {      {"\x20\xe4\xbd\xa0\\t\xe5\xa5\xbd,\\r!\\n",       "\x20\xe4\xbd\xa0\t\xe5\xa5\xbd,\r!\n"},      {"\xe8\xa9\xa6\xe9\xa8\x93\\\' means \\\"test\\\"",       "\xe8\xa9\xa6\xe9\xa8\x93\' means \"test\""},      {"\\\\\xe6\x88\x91\\\\:\\\\\xe6\x9d\xa8\xe6\xac\xa2\\\\",       "\\\xe6\x88\x91\\:\\\xe6\x9d\xa8\xe6\xac\xa2\\"},      {"\xed\x81\xac\xeb\xa1\xac\\x08\\t\\n\\x0b\\x0c\\r",       "\xed\x81\xac\xeb\xa1\xac\010\011\012\013\014\015"}  };  for (const epair& val : oct_values) {    std::string escaped = absl::CEscape(val.unescaped);    EXPECT_EQ(escaped, val.escaped);  }  for (const epair& val : hex_values) {    std::string escaped = absl::CHexEscape(val.unescaped);    EXPECT_EQ(escaped, val.escaped);  }  for (const epair& val : utf8_oct_values) {    std::string escaped = absl::Utf8SafeCEscape(val.unescaped);    EXPECT_EQ(escaped, val.escaped);  }  for (const epair& val : utf8_hex_values) {    std::string escaped = absl::Utf8SafeCHexEscape(val.unescaped);    EXPECT_EQ(escaped, val.escaped);  }}TEST(Unescape, BasicFunction) {  epair tests[] =    {{"\\u0030", "0"},     {"\\u00A3", "\xC2\xA3"},     {"\\u22FD", "\xE2\x8B\xBD"},     {"\\U00010000", "\xF0\x90\x80\x80"},     {"\\U0010FFFD", "\xF4\x8F\xBF\xBD"}};  for (const epair& val : tests) {    std::string out;    EXPECT_TRUE(absl::CUnescape(val.escaped, &out));    EXPECT_EQ(out, val.unescaped);  }  std::string bad[] =     {"\\u1",  // too short      "\\U1",  // too short      "\\Uffffff",      "\\777",  // exceeds 0xff      "\\xABCD"};  // exceeds 0xff  for (const std::string& e : bad) {    std::string error;    std::string out;    EXPECT_FALSE(absl::CUnescape(e, &out, &error));    EXPECT_FALSE(error.empty());  }}class CUnescapeTest : public testing::Test { protected:  static const char kStringWithMultipleOctalNulls[];  static const char kStringWithMultipleHexNulls[];  static const char kStringWithMultipleUnicodeNulls[];  std::string result_string_;};const char CUnescapeTest::kStringWithMultipleOctalNulls[] =    "\\0\\n"    // null escape \0 plus newline    "0\\n"      // just a number 0 (not a null escape) plus newline    "\\00\\12"  // null escape \00 plus octal newline code    "\\000";    // null escape \000// This has the same ingredients as kStringWithMultipleOctalNulls// but with \x hex escapes instead of octal escapes.const char CUnescapeTest::kStringWithMultipleHexNulls[] =    "\\x0\\n"    "0\\n"    "\\x00\\xa"    "\\x000";const char CUnescapeTest::kStringWithMultipleUnicodeNulls[] =    "\\u0000\\n"    // short-form (4-digit) null escape plus newline    "0\\n"          // just a number 0 (not a null escape) plus newline    "\\U00000000";  // long-form (8-digit) null escapeTEST_F(CUnescapeTest, Unescapes1CharOctalNull) {  std::string original_string = "\\0";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes2CharOctalNull) {  std::string original_string = "\\00";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes3CharOctalNull) {  std::string original_string = "\\000";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes1CharHexNull) {  std::string original_string = "\\x0";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes2CharHexNull) {  std::string original_string = "\\x00";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes3CharHexNull) {  std::string original_string = "\\x000";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes4CharUnicodeNull) {  std::string original_string = "\\u0000";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, Unescapes8CharUnicodeNull) {  std::string original_string = "\\U00000000";  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0", 1), result_string_);}TEST_F(CUnescapeTest, UnescapesMultipleOctalNulls) {  std::string original_string(kStringWithMultipleOctalNulls);  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  // All escapes, including newlines and null escapes, should have been  // converted to the equivalent characters.  EXPECT_EQ(std::string("\0\n"                   "0\n"                   "\0\n"                   "\0", 7), result_string_);}TEST_F(CUnescapeTest, UnescapesMultipleHexNulls) {  std::string original_string(kStringWithMultipleHexNulls);  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0\n"                   "0\n"                   "\0\n"                   "\0", 7), result_string_);}TEST_F(CUnescapeTest, UnescapesMultipleUnicodeNulls) {  std::string original_string(kStringWithMultipleUnicodeNulls);  EXPECT_TRUE(absl::CUnescape(original_string, &result_string_));  EXPECT_EQ(std::string("\0\n"                   "0\n"                   "\0", 5), result_string_);}static struct {  absl::string_view plaintext;  absl::string_view cyphertext;} const base64_tests[] = {    // Empty std::string.    {{"", 0}, {"", 0}},    {{nullptr, 0},     {"", 0}},  // if length is zero, plaintext ptr must be ignored!    // Basic bit patterns;    // values obtained with "echo -n '...' | uuencode -m test"    {{"\000", 1}, "AA=="},    {{"\001", 1}, "AQ=="},    {{"\002", 1}, "Ag=="},    {{"\004", 1}, "BA=="},    {{"\010", 1}, "CA=="},    {{"\020", 1}, "EA=="},    {{"\040", 1}, "IA=="},    {{"\100", 1}, "QA=="},    {{"\200", 1}, "gA=="},    {{"\377", 1}, "/w=="},    {{"\376", 1}, "/g=="},    {{"\375", 1}, "/Q=="},    {{"\373", 1}, "+w=="},    {{"\367", 1}, "9w=="},    {{"\357", 1}, "7w=="},    {{"\337", 1}, "3w=="},    {{"\277", 1}, "vw=="},    {{"\177", 1}, "fw=="},    {{"\000\000", 2}, "AAA="},    {{"\000\001", 2}, "AAE="},    {{"\000\002", 2}, "AAI="},    {{"\000\004", 2}, "AAQ="},    {{"\000\010", 2}, "AAg="},    {{"\000\020", 2}, "ABA="},    {{"\000\040", 2}, "ACA="},    {{"\000\100", 2}, "AEA="},    {{"\000\200", 2}, "AIA="},    {{"\001\000", 2}, "AQA="},    {{"\002\000", 2}, "AgA="},    {{"\004\000", 2}, "BAA="},    {{"\010\000", 2}, "CAA="},    {{"\020\000", 2}, "EAA="},    {{"\040\000", 2}, "IAA="},    {{"\100\000", 2}, "QAA="},    {{"\200\000", 2}, "gAA="},    {{"\377\377", 2}, "//8="},    {{"\377\376", 2}, "//4="},    {{"\377\375", 2}, "//0="},    {{"\377\373", 2}, "//s="},    {{"\377\367", 2}, "//c="},    {{"\377\357", 2}, "/+8="},    {{"\377\337", 2}, "/98="},    {{"\377\277", 2}, "/78="},    {{"\377\177", 2}, "/38="},    {{"\376\377", 2}, "/v8="},    {{"\375\377", 2}, "/f8="},    {{"\373\377", 2}, "+/8="},    {{"\367\377", 2}, "9/8="},    {{"\357\377", 2}, "7/8="},    {{"\337\377", 2}, "3/8="},    {{"\277\377", 2}, "v/8="},    {{"\177\377", 2}, "f/8="},    {{"\000\000\000", 3}, "AAAA"},    {{"\000\000\001", 3}, "AAAB"},    {{"\000\000\002", 3}, "AAAC"},    {{"\000\000\004", 3}, "AAAE"},    {{"\000\000\010", 3}, "AAAI"},    {{"\000\000\020", 3}, "AAAQ"},    {{"\000\000\040", 3}, "AAAg"},    {{"\000\000\100", 3}, "AABA"},    {{"\000\000\200", 3}, "AACA"},    {{"\000\001\000", 3}, "AAEA"},    {{"\000\002\000", 3}, "AAIA"},    {{"\000\004\000", 3}, "AAQA"},    {{"\000\010\000", 3}, "AAgA"},    {{"\000\020\000", 3}, "ABAA"},    {{"\000\040\000", 3}, "ACAA"},    {{"\000\100\000", 3}, "AEAA"},    {{"\000\200\000", 3}, "AIAA"},    {{"\001\000\000", 3}, "AQAA"},    {{"\002\000\000", 3}, "AgAA"},    {{"\004\000\000", 3}, "BAAA"},    {{"\010\000\000", 3}, "CAAA"},    {{"\020\000\000", 3}, "EAAA"},    {{"\040\000\000", 3}, "IAAA"},    {{"\100\000\000", 3}, "QAAA"},    {{"\200\000\000", 3}, "gAAA"},    {{"\377\377\377", 3}, "////"},    {{"\377\377\376", 3}, "///+"},    {{"\377\377\375", 3}, "///9"},    {{"\377\377\373", 3}, "///7"},    {{"\377\377\367", 3}, "///3"},    {{"\377\377\357", 3}, "///v"},    {{"\377\377\337", 3}, "///f"},    {{"\377\377\277", 3}, "//+/"},    {{"\377\377\177", 3}, "//9/"},    {{"\377\376\377", 3}, "//7/"},    {{"\377\375\377", 3}, "//3/"},    {{"\377\373\377", 3}, "//v/"},    {{"\377\367\377", 3}, "//f/"},    {{"\377\357\377", 3}, "/+//"},    {{"\377\337\377", 3}, "/9//"},    {{"\377\277\377", 3}, "/7//"},    {{"\377\177\377", 3}, "/3//"},    {{"\376\377\377", 3}, "/v//"},    {{"\375\377\377", 3}, "/f//"},    {{"\373\377\377", 3}, "+///"},    {{"\367\377\377", 3}, "9///"},    {{"\357\377\377", 3}, "7///"},    {{"\337\377\377", 3}, "3///"},    {{"\277\377\377", 3}, "v///"},    {{"\177\377\377", 3}, "f///"},    // Random numbers: values obtained with    //    //  #! /bin/bash    //  dd bs=$1 count=1 if=/dev/random of=/tmp/bar.random    //  od -N $1 -t o1 /tmp/bar.random    //  uuencode -m test < /tmp/bar.random    //    // where $1 is the number of bytes (2, 3)    {{"\243\361", 2}, "o/E="},    {{"\024\167", 2}, "FHc="},    {{"\313\252", 2}, "y6o="},    {{"\046\041", 2}, "JiE="},    {{"\145\236", 2}, "ZZ4="},    {{"\254\325", 2}, "rNU="},    {{"\061\330", 2}, "Mdg="},    {{"\245\032", 2}, "pRo="},    {{"\006\000", 2}, "BgA="},    {{"\375\131", 2}, "/Vk="},    {{"\303\210", 2}, "w4g="},    {{"\040\037", 2}, "IB8="},    {{"\261\372", 2}, "sfo="},    {{"\335\014", 2}, "3Qw="},    {{"\233\217", 2}, "m48="},    {{"\373\056", 2}, "+y4="},    {{"\247\232", 2}, "p5o="},    {{"\107\053", 2}, "Rys="},    {{"\204\077", 2}, "hD8="},    {{"\276\211", 2}, "vok="},    {{"\313\110", 2}, "y0g="},    {{"\363\376", 2}, "8/4="},    {{"\251\234", 2}, "qZw="},    {{"\103\262", 2}, "Q7I="},    {{"\142\312", 2}, "Yso="},    {{"\067\211", 2}, "N4k="},    {{"\220\001", 2}, "kAE="},    {{"\152\240", 2}, "aqA="},    {{"\367\061", 2}, "9zE="},    {{"\133\255", 2}, "W60="},    {{"\176\035", 2}, "fh0="},    {{"\032\231", 2}, "Gpk="},    {{"\013\007\144", 3}, "Cwdk"},    {{"\030\112\106", 3}, "GEpG"},    {{"\047\325\046", 3}, "J9Um"},    {{"\310\160\022", 3}, "yHAS"},    {{"\131\100\237", 3}, "WUCf"},    {{"\064\342\134", 3}, "NOJc"},    {{"\010\177\004", 3}, "CH8E"},    {{"\345\147\205", 3}, "5WeF"},    {{"\300\343\360", 3}, "wOPw"},    {{"\061\240\201", 3}, "MaCB"},    {{"\225\333\044", 3}, "ldsk"},    {{"\215\137\352", 3}, "jV/q"},    {{"\371\147\160", 3}, "+Wdw"},    {{"\030\320\051", 3}, "GNAp"},    {{"\044\174\241", 3}, "JHyh"},    {{"\260\127\037", 3}, "sFcf"},    {{"\111\045\033", 3}, "SSUb"},    {{"\202\114\107", 3}, "gkxH"},    {{"\057\371\042", 3}, "L/ki"},    {{"\223\247\244", 3}, "k6ek"},    {{"\047\216\144", 3}, "J45k"},    {{"\203\070\327", 3}, "gzjX"},    {{"\247\140\072", 3}, "p2A6"},    {{"\124\115\116", 3}, "VE1O"},    {{"\157\162\050", 3}, "b3Io"},    {{"\357\223\004", 3}, "75ME"},    {{"\052\117\156", 3}, "Kk9u"},    {{"\347\154\000", 3}, "52wA"},    {{"\303\012\142", 3}, "wwpi"},    {{"\060\035\362", 3}, "MB3y"},    {{"\130\226\361", 3}, "WJbx"},    {{"\173\013\071", 3}, "ews5"},    {{"\336\004\027", 3}, "3gQX"},    {{"\357\366\234", 3}, "7/ac"},    {{"\353\304\111", 3}, "68RJ"},    {{"\024\264\131", 3}, "FLRZ"},    {{"\075\114\251", 3}, "PUyp"},    {{"\315\031\225", 3}, "zRmV"},    {{"\154\201\276", 3}, "bIG+"},    {{"\200\066\072", 3}, "gDY6"},    {{"\142\350\267", 3}, "Yui3"},    {{"\033\000\166", 3}, "GwB2"},    {{"\210\055\077", 3}, "iC0/"},    {{"\341\037\124", 3}, "4R9U"},    {{"\161\103\152", 3}, "cUNq"},    {{"\270\142\131", 3}, "uGJZ"},    {{"\337\076\074", 3}, "3z48"},    {{"\375\106\362", 3}, "/Uby"},    {{"\227\301\127", 3}, "l8FX"},    {{"\340\002\234", 3}, "4AKc"},    {{"\121\064\033", 3}, "UTQb"},    {{"\157\134\143", 3}, "b1xj"},    {{"\247\055\327", 3}, "py3X"},    {{"\340\142\005", 3}, "4GIF"},    {{"\060\260\143", 3}, "MLBj"},    {{"\075\203\170", 3}, "PYN4"},    {{"\143\160\016", 3}, "Y3AO"},    {{"\313\013\063", 3}, "ywsz"},    {{"\174\236\135", 3}, "fJ5d"},    {{"\103\047\026", 3}, "QycW"},    {{"\365\005\343", 3}, "9QXj"},    {{"\271\160\223", 3}, "uXCT"},    {{"\362\255\172", 3}, "8q16"},    {{"\113\012\015", 3}, "SwoN"},    // various lengths, generated by this python script:    //    // from std::string import lowercase as lc    // for i in range(27):    //   print '{ %2d, "%s",%s "%s" },' % (i, lc[:i], ' ' * (26-i),    //                                     lc[:i].encode('base64').strip())    {{"", 0}, {"", 0}},    {"a", "YQ=="},    {"ab", "YWI="},    {"abc", "YWJj"},    {"abcd", "YWJjZA=="},    {"abcde", "YWJjZGU="},    {"abcdef", "YWJjZGVm"},    {"abcdefg", "YWJjZGVmZw=="},    {"abcdefgh", "YWJjZGVmZ2g="},    {"abcdefghi", "YWJjZGVmZ2hp"},    {"abcdefghij", "YWJjZGVmZ2hpag=="},    {"abcdefghijk", "YWJjZGVmZ2hpams="},    {"abcdefghijkl", "YWJjZGVmZ2hpamts"},    {"abcdefghijklm", "YWJjZGVmZ2hpamtsbQ=="},    {"abcdefghijklmn", "YWJjZGVmZ2hpamtsbW4="},    {"abcdefghijklmno", "YWJjZGVmZ2hpamtsbW5v"},    {"abcdefghijklmnop", "YWJjZGVmZ2hpamtsbW5vcA=="},    {"abcdefghijklmnopq", "YWJjZGVmZ2hpamtsbW5vcHE="},    {"abcdefghijklmnopqr", "YWJjZGVmZ2hpamtsbW5vcHFy"},    {"abcdefghijklmnopqrs", "YWJjZGVmZ2hpamtsbW5vcHFycw=="},    {"abcdefghijklmnopqrst", "YWJjZGVmZ2hpamtsbW5vcHFyc3Q="},    {"abcdefghijklmnopqrstu", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1"},    {"abcdefghijklmnopqrstuv", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dg=="},    {"abcdefghijklmnopqrstuvw", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnc="},    {"abcdefghijklmnopqrstuvwx", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4"},    {"abcdefghijklmnopqrstuvwxy", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eQ=="},    {"abcdefghijklmnopqrstuvwxyz", "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="},};TEST(Base64, EscapeAndUnescape) {  // Check the short strings; this tests the math (and boundaries)  for (const auto& tc : base64_tests) {    std::string encoded("this junk should be ignored");    absl::Base64Escape(tc.plaintext, &encoded);    EXPECT_EQ(encoded, tc.cyphertext);    std::string decoded("this junk should be ignored");    EXPECT_TRUE(absl::Base64Unescape(encoded, &decoded));    EXPECT_EQ(decoded, tc.plaintext);    std::string websafe(tc.cyphertext);    for (int c = 0; c < websafe.size(); ++c) {      if ('+' == websafe[c]) websafe[c] = '-';      if ('/' == websafe[c]) websafe[c] = '_';      if ('=' == websafe[c]) {        websafe.resize(c);        break;      }    }    encoded = "this junk should be ignored";    absl::WebSafeBase64Escape(tc.plaintext, &encoded);    EXPECT_EQ(encoded, websafe);    // Let's try the std::string version of the decoder    decoded = "this junk should be ignored";    EXPECT_TRUE(absl::WebSafeBase64Unescape(websafe, &decoded));    EXPECT_EQ(decoded, tc.plaintext);  }  // Now try the long strings, this tests the streaming  for (const auto& tc : base64_strings) {    std::string buffer;    absl::WebSafeBase64Escape(tc.plaintext, &buffer);    EXPECT_EQ(tc.cyphertext, buffer);  }  // Verify the behavior when decoding bad data  {    absl::string_view data_set[] = {"ab-/", absl::string_view("\0bcd", 4),                                    absl::string_view("abc.\0", 5)};    for (absl::string_view bad_data : data_set) {      std::string buf;      EXPECT_FALSE(absl::Base64Unescape(bad_data, &buf));      EXPECT_FALSE(absl::WebSafeBase64Unescape(bad_data, &buf));      EXPECT_TRUE(buf.empty());    }  }}TEST(Base64, DISABLED_HugeData) {  const size_t kSize = size_t(3) * 1000 * 1000 * 1000;  static_assert(kSize % 3 == 0, "kSize must be divisible by 3");  const std::string huge(kSize, 'x');  std::string escaped;  absl::Base64Escape(huge, &escaped);  // Generates the std::string that should match a base64 encoded "xxx..." std::string.  // "xxx" in base64 is "eHh4".  std::string expected_encoding;  expected_encoding.reserve(kSize / 3 * 4);  for (size_t i = 0; i < kSize / 3; ++i) {    expected_encoding.append("eHh4");  }  EXPECT_EQ(expected_encoding, escaped);  std::string unescaped;  EXPECT_TRUE(absl::Base64Unescape(escaped, &unescaped));  EXPECT_EQ(huge, unescaped);}TEST(HexAndBack, HexStringToBytes_and_BytesToHexString) {  std::string hex_mixed = "0123456789abcdefABCDEF";  std::string bytes_expected = "\x01\x23\x45\x67\x89\xab\xcd\xef\xAB\xCD\xEF";  std::string hex_only_lower = "0123456789abcdefabcdef";  std::string bytes_result = absl::HexStringToBytes(hex_mixed);  EXPECT_EQ(bytes_expected, bytes_result);  std::string prefix_valid = hex_mixed + "?";  std::string prefix_valid_result = absl::HexStringToBytes(      absl::string_view(prefix_valid.data(), prefix_valid.size() - 1));  EXPECT_EQ(bytes_expected, prefix_valid_result);  std::string infix_valid = "?" + hex_mixed + "???";  std::string infix_valid_result = absl::HexStringToBytes(      absl::string_view(infix_valid.data() + 1, hex_mixed.size()));  EXPECT_EQ(bytes_expected, infix_valid_result);  std::string hex_result = absl::BytesToHexString(bytes_expected);  EXPECT_EQ(hex_only_lower, hex_result);}}  // namespace
 |