15 #include "absl/strings/escaping.h"
25 #include "absl/base/internal/endian.h"
26 #include "absl/base/internal/raw_logging.h"
27 #include "absl/base/internal/unaligned_access.h"
28 #include "absl/strings/internal/char_map.h"
29 #include "absl/strings/internal/escaping.h"
30 #include "absl/strings/internal/resize_uninitialized.h"
31 #include "absl/strings/internal/utf8.h"
32 #include "absl/strings/str_cat.h"
33 #include "absl/strings/str_join.h"
34 #include "absl/strings/string_view.h"
46 static_assert(
'0' == 0x30 &&
'A' == 0x41 &&
'a' == 0x61,
47 "Character set must be ASCII.");
49 int x =
static_cast<unsigned char>(c);
57 if (c >= 0xD800 && c <= 0xDFFF) {
87 const char* p = source.
data();
88 const char*
end = p + source.
size();
89 const char* last_byte =
end - 1;
92 while (p == d && p <
end && *p !=
'\\') p++, d++;
98 if (++p > last_byte) {
99 if (
error) *
error =
"String cannot end with \\";
103 case 'a': *d++ =
'\a';
break;
104 case 'b': *d++ =
'\b';
break;
105 case 'f': *d++ =
'\f';
break;
106 case 'n': *d++ =
'\n';
break;
107 case 'r': *d++ =
'\r';
break;
108 case 't': *d++ =
'\t';
break;
109 case 'v': *d++ =
'\v';
break;
110 case '\\': *d++ =
'\\';
break;
111 case '?': *d++ =
'\?';
break;
112 case '\'': *d++ =
'\'';
break;
113 case '"': *d++ =
'\"';
break;
123 const char* octal_start = p;
124 unsigned int ch = *p -
'0';
127 ch =
ch * 8 + *++p -
'0';
130 *
error =
"Value of \\" +
136 if ((
ch == 0) && leave_nulls_escaped) {
138 const ptrdiff_t octal_size = p + 1 - octal_start;
140 memmove(d, octal_start, octal_size);
149 if (p >= last_byte) {
150 if (
error) *
error =
"String cannot end with \\x";
153 if (
error) *
error =
"\\x cannot be followed by a non-hex digit";
157 const char* hex_start = p;
163 *
error =
"Value of \\" +
169 if ((
ch == 0) && leave_nulls_escaped) {
171 const ptrdiff_t hex_size = p + 1 - hex_start;
173 memmove(d, hex_start, hex_size);
183 const char* hex_start = p;
186 *
error =
"\\u must be followed by 4 hex digits: \\" +
191 for (
int i = 0;
i < 4; ++
i) {
197 *
error =
"\\u must be followed by 4 hex digits: \\" +
203 if ((rune == 0) && leave_nulls_escaped) {
206 memmove(d, hex_start, 5);
219 const char* hex_start = p;
222 *
error =
"\\U must be followed by 8 hex digits: \\" +
227 for (
int i = 0;
i < 8; ++
i) {
233 if (newrune > 0x10FFFF) {
235 *
error =
"Value of \\" +
237 " exceeds Unicode limit (0x10FFFF)";
245 *
error =
"\\U must be followed by 8 hex digits: \\" +
251 if ((rune == 0) && leave_nulls_escaped) {
254 memmove(d, hex_start, 9);
272 *dest_len = d -
dest;
294 dest->erase(dest_size);
312 bool last_hex_escape =
false;
314 for (
unsigned char c : src) {
315 bool is_hex_escape =
false;
317 case '\n':
dest.append(
"\\" "n");
break;
318 case '\r':
dest.append(
"\\" "r");
break;
319 case '\t':
dest.append(
"\\" "t");
break;
320 case '\"':
dest.append(
"\\" "\"");
break;
321 case '\'':
dest.append(
"\\" "'");
break;
322 case '\\':
dest.append(
"\\" "\\");
break;
327 if ((!utf8_safe || c < 0x80) &&
331 dest.append(
"\\" "x");
334 is_hex_escape =
true;
346 last_hex_escape = is_hex_escape;
354 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 2, 4, 4,
355 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
356 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
357 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
358 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
359 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1,
360 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
361 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
362 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
363 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
364 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
365 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
366 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
367 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
368 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
369 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
377 size_t escaped_len = 0;
384 if (escaped_len == src.
size()) {
389 size_t cur_dest_len =
dest->size();
391 cur_dest_len + escaped_len);
392 char* append_ptr = &(*dest)[cur_dest_len];
394 for (
unsigned char c : src) {
398 }
else if (char_len == 2) {
401 *append_ptr++ =
'\\';
405 *append_ptr++ =
'\\';
409 *append_ptr++ =
'\\';
413 *append_ptr++ =
'\\';
414 *append_ptr++ =
'\"';
417 *append_ptr++ =
'\\';
418 *append_ptr++ =
'\'';
421 *append_ptr++ =
'\\';
422 *append_ptr++ =
'\\';
426 *append_ptr++ =
'\\';
427 *append_ptr++ =
'0' + c / 64;
428 *append_ptr++ =
'0' + (c % 64) / 8;
429 *append_ptr++ =
'0' + c % 8;
435 size_t szdest,
const signed char* unbase64,
437 static const char kPad64Equals =
'=';
438 static const char kPad64Dot =
'.';
444 unsigned int temp = 0;
449 const unsigned char* src =
reinterpret_cast<const unsigned char*
>(src_param);
457 #define GET_INPUT(label, remain) \
461 decode = unbase64[ch]; \
463 if (absl::ascii_isspace(ch) && szsrc >= remain) goto label; \
464 state = 4 - remain; \
489 if (!src[0] || !src[1] || !src[2] ||
490 ((
temp = ((
unsigned(unbase64[src[0]]) << 18) |
491 (
unsigned(unbase64[src[1]]) << 12) |
492 (
unsigned(unbase64[src[2]]) << 6) |
493 (
unsigned(unbase64[src[3]])))) &
520 if (destidx + 3 > szdest)
return false;
530 if (!src[0] || !src[1] || !src[2] ||
531 ((
temp = ((
unsigned(unbase64[src[0]]) << 18) |
532 (
unsigned(unbase64[src[1]]) << 12) |
533 (
unsigned(unbase64[src[2]]) << 6) |
534 (
unsigned(unbase64[src[3]])))) &
552 if (
decode < 0 &&
ch != kPad64Equals &&
ch != kPad64Dot &&
556 if (
ch == kPad64Equals ||
ch == kPad64Dot) {
574 }
else if (
ch == kPad64Equals ||
ch == kPad64Dot) {
592 if (destidx + 3 > szdest)
return false;
607 int expected_equals = 0;
620 if (destidx + 1 > szdest)
return false;
631 if (destidx + 2 > szdest)
return false;
654 if (*src == kPad64Equals || *src == kPad64Dot)
662 const bool ok = (equals == 0 || equals == expected_equals);
663 if (
ok) *
len = destidx;
698 -1, -1, -1, -1, -1, -1, -1, -1,
699 -1, -1, -1, -1, -1, -1, -1, -1,
700 -1, -1, -1, -1, -1, -1, -1, -1,
701 -1, -1, -1, -1, -1, -1, -1, -1,
702 -1, -1, -1, -1, -1, -1, -1, -1,
703 -1, -1, -1, 62, -1, -1, -1, 63,
704 52, 53, 54, 55, 56, 57, 58, 59,
705 60, 61, -1, -1, -1, -1, -1, -1,
706 -1, 0, 1, 2, 3, 4, 5, 6,
707 07, 8, 9, 10, 11, 12, 13, 14,
708 15, 16, 17, 18, 19, 20, 21, 22,
709 23, 24, 25, -1, -1, -1, -1, -1,
710 -1, 26, 27, 28, 29, 30, 31, 32,
711 33, 34, 35, 36, 37, 38, 39, 40,
712 41, 42, 43, 44, 45, 46, 47, 48,
713 49, 50, 51, -1, -1, -1, -1, -1,
714 -1, -1, -1, -1, -1, -1, -1, -1,
715 -1, -1, -1, -1, -1, -1, -1, -1,
716 -1, -1, -1, -1, -1, -1, -1, -1,
717 -1, -1, -1, -1, -1, -1, -1, -1,
718 -1, -1, -1, -1, -1, -1, -1, -1,
719 -1, -1, -1, -1, -1, -1, -1, -1,
720 -1, -1, -1, -1, -1, -1, -1, -1,
721 -1, -1, -1, -1, -1, -1, -1, -1,
722 -1, -1, -1, -1, -1, -1, -1, -1,
723 -1, -1, -1, -1, -1, -1, -1, -1,
724 -1, -1, -1, -1, -1, -1, -1, -1,
725 -1, -1, -1, -1, -1, -1, -1, -1,
726 -1, -1, -1, -1, -1, -1, -1, -1,
727 -1, -1, -1, -1, -1, -1, -1, -1,
728 -1, -1, -1, -1, -1, -1, -1, -1,
729 -1, -1, -1, -1, -1, -1, -1, -1
733 -1, -1, -1, -1, -1, -1, -1, -1,
734 -1, -1, -1, -1, -1, -1, -1, -1,
735 -1, -1, -1, -1, -1, -1, -1, -1,
736 -1, -1, -1, -1, -1, -1, -1, -1,
737 -1, -1, -1, -1, -1, -1, -1, -1,
738 -1, -1, -1, -1, -1, 62, -1, -1,
739 52, 53, 54, 55, 56, 57, 58, 59,
740 60, 61, -1, -1, -1, -1, -1, -1,
741 -1, 0, 1, 2, 3, 4, 5, 6,
742 07, 8, 9, 10, 11, 12, 13, 14,
743 15, 16, 17, 18, 19, 20, 21, 22,
744 23, 24, 25, -1, -1, -1, -1, 63,
745 -1, 26, 27, 28, 29, 30, 31, 32,
746 33, 34, 35, 36, 37, 38, 39, 40,
747 41, 42, 43, 44, 45, 46, 47, 48,
748 49, 50, 51, -1, -1, -1, -1, -1,
749 -1, -1, -1, -1, -1, -1, -1, -1,
750 -1, -1, -1, -1, -1, -1, -1, -1,
751 -1, -1, -1, -1, -1, -1, -1, -1,
752 -1, -1, -1, -1, -1, -1, -1, -1,
753 -1, -1, -1, -1, -1, -1, -1, -1,
754 -1, -1, -1, -1, -1, -1, -1, -1,
755 -1, -1, -1, -1, -1, -1, -1, -1,
756 -1, -1, -1, -1, -1, -1, -1, -1,
757 -1, -1, -1, -1, -1, -1, -1, -1,
758 -1, -1, -1, -1, -1, -1, -1, -1,
759 -1, -1, -1, -1, -1, -1, -1, -1,
760 -1, -1, -1, -1, -1, -1, -1, -1,
761 -1, -1, -1, -1, -1, -1, -1, -1,
762 -1, -1, -1, -1, -1, -1, -1, -1,
763 -1, -1, -1, -1, -1, -1, -1, -1,
764 -1, -1, -1, -1, -1, -1, -1, -1
769 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
771 template <
typename String>
773 const signed char* unbase64) {
777 const size_t dest_len = 3 * (slen / 4) + (slen % 4);
792 assert(
len <= dest_len);
800 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
801 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
802 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
803 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
804 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
805 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
806 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
807 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
823 template <
typename T>
825 for (
int i = 0;
i <
num;
i++) {
833 template <
typename T>
835 auto dest_ptr = &
dest[0];
836 for (
auto src_ptr = src; src_ptr != (src +
num); ++src_ptr, dest_ptr += 2) {
906 reinterpret_cast<const unsigned char*
>(src.
data()), src.
size(),
dest,
912 reinterpret_cast<const unsigned char*
>(src.
data()), src.
size(),
dest,
919 reinterpret_cast<const unsigned char*
>(src.
data()), src.
size(), &
dest,
927 reinterpret_cast<const unsigned char*
>(src.
data()), src.
size(), &
dest,
934 const auto num =
from.size() / 2;
936 absl::HexStringToBytesInternal<std::string&>(
from.data(),
result,
num);
943 absl::BytesToHexStringInternal<std::string&>(
944 reinterpret_cast<const unsigned char*
>(
from.data()),
result,
from.size());