diff options
Diffstat (limited to 'absl/strings/internal/escaping.cc')
-rw-r--r-- | absl/strings/internal/escaping.cc | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/absl/strings/internal/escaping.cc b/absl/strings/internal/escaping.cc index cfea0961..56a4cbed 100644 --- a/absl/strings/internal/escaping.cc +++ b/absl/strings/internal/escaping.cc @@ -21,26 +21,26 @@ namespace absl { ABSL_NAMESPACE_BEGIN namespace strings_internal { +// The two strings below provide maps from normal 6-bit characters to their +// base64-escaped equivalent. +// For the inverse case, see kUn(WebSafe)Base64 in the external +// escaping.cc. ABSL_CONST_INIT const char kBase64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +ABSL_CONST_INIT const char kWebSafeBase64Chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + + size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { // Base64 encodes three bytes of input at a time. If the input is not // divisible by three, we pad as appropriate. // - // (from https://tools.ietf.org/html/rfc3548) - // Special processing is performed if fewer than 24 bits are available - // at the end of the data being encoded. A full encoding quantum is - // always completed at the end of a quantity. When fewer than 24 input - // bits are available in an input group, zero bits are added (on the - // right) to form an integral number of 6-bit groups. Padding at the - // end of the data is performed using the '=' character. Since all base - // 64 input is an integral number of octets, only the following cases - // can arise: - // Base64 encodes each three bytes of input into four bytes of output. size_t len = (input_len / 3) * 4; + // Since all base 64 input is an integral number of octets, only the following + // cases can arise: if (input_len % 3 == 0) { // (from https://tools.ietf.org/html/rfc3548) // (1) the final quantum of encoding input is an integral multiple of 24 @@ -70,6 +70,21 @@ size_t CalculateBase64EscapedLenInternal(size_t input_len, bool do_padding) { return len; } +// ---------------------------------------------------------------------- +// Take the input in groups of 4 characters and turn each +// character into a code 0 to 63 thus: +// A-Z map to 0 to 25 +// a-z map to 26 to 51 +// 0-9 map to 52 to 61 +// +(- for WebSafe) maps to 62 +// /(_ for WebSafe) maps to 63 +// There will be four numbers, all less than 64 which can be represented +// by a 6 digit binary number (aaaaaa, bbbbbb, cccccc, dddddd respectively). +// Arrange the 6 digit binary numbers into three bytes as such: +// aaaaaabb bbbbcccc ccdddddd +// Equals signs (one or two) are used at the end of the encoded block to +// indicate that the text was not an integer multiple of three bytes long. +// ---------------------------------------------------------------------- size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, size_t szdest, const char* base64, bool do_padding) { @@ -83,6 +98,16 @@ size_t Base64EscapeInternal(const unsigned char* src, size_t szsrc, char* dest, char* const limit_dest = dest + szdest; const unsigned char* const limit_src = src + szsrc; + // (from https://tools.ietf.org/html/rfc3548) + // Special processing is performed if fewer than 24 bits are available + // at the end of the data being encoded. A full encoding quantum is + // always completed at the end of a quantity. When fewer than 24 input + // bits are available in an input group, zero bits are added (on the + // right) to form an integral number of 6-bit groups. + // + // If do_padding is true, padding at the end of the data is performed. This + // output padding uses the '=' character. + // Three bytes of data encodes to four characters of cyphertext. // So we can pump through three-byte chunks atomically. if (szsrc >= 3) { // "limit_src - 3" is UB if szsrc < 3. |