diff options
author | Juan José Arboleda <soyjuanarbol@gmail.com> | 2020-08-25 23:31:11 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2020-09-30 18:53:35 +0300 |
commit | ff4cf817a3159ddf7c4bf898819f88445c5fee53 (patch) | |
tree | edbca8efc08eec6297be0e3bb088f9bf3e07b1bc /src/base64.h | |
parent | a8806535d9e7db7bf20b3b3ef8f911320baf7511 (diff) |
src: create helper for reading Uint32BE
Fixes: https://github.com/nodejs/node/issues/34827
PR-URL: https://github.com/nodejs/node/pull/34944
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/base64.h')
-rw-r--r-- | src/base64.h | 78 |
1 files changed, 3 insertions, 75 deletions
diff --git a/src/base64.h b/src/base64.h index 1cb90bdeba7..24fc57e1d60 100644 --- a/src/base64.h +++ b/src/base64.h @@ -4,6 +4,7 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include "util.h" +#include "base64-inl.h" #include <cstddef> #include <cstdint> @@ -20,6 +21,8 @@ static inline constexpr size_t base64_decoded_size_fast(size_t size) { return size > 1 ? (size / 4) * 3 + (size % 4 + 1) / 2 : 0; } +inline uint32_t ReadUint32BE(const unsigned char* p); + template <typename TypeName> size_t base64_decoded_size(const TypeName* src, size_t size) { // 1-byte input cannot be decoded @@ -34,81 +37,6 @@ size_t base64_decoded_size(const TypeName* src, size_t size) { return base64_decoded_size_fast(size); } - -extern const int8_t unbase64_table[256]; - - -inline static int8_t unbase64(uint8_t x) { - return unbase64_table[x]; -} - - -template <typename TypeName> -bool base64_decode_group_slow(char* const dst, const size_t dstlen, - const TypeName* const src, const size_t srclen, - size_t* const i, size_t* const k) { - uint8_t hi; - uint8_t lo; -#define V(expr) \ - for (;;) { \ - const uint8_t c = src[*i]; \ - lo = unbase64(c); \ - *i += 1; \ - if (lo < 64) \ - break; /* Legal character. */ \ - if (c == '=' || *i >= srclen) \ - return false; /* Stop decoding. */ \ - } \ - expr; \ - if (*i >= srclen) \ - return false; \ - if (*k >= dstlen) \ - return false; \ - hi = lo; - V(/* Nothing. */); - V(dst[(*k)++] = ((hi & 0x3F) << 2) | ((lo & 0x30) >> 4)); - V(dst[(*k)++] = ((hi & 0x0F) << 4) | ((lo & 0x3C) >> 2)); - V(dst[(*k)++] = ((hi & 0x03) << 6) | ((lo & 0x3F) >> 0)); -#undef V - return true; // Continue decoding. -} - - -template <typename TypeName> -size_t base64_decode_fast(char* const dst, const size_t dstlen, - const TypeName* const src, const size_t srclen, - const size_t decoded_size) { - const size_t available = dstlen < decoded_size ? dstlen : decoded_size; - const size_t max_k = available / 3 * 3; - size_t max_i = srclen / 4 * 4; - size_t i = 0; - size_t k = 0; - while (i < max_i && k < max_k) { - const uint32_t v = - unbase64(src[i + 0]) << 24 | - unbase64(src[i + 1]) << 16 | - unbase64(src[i + 2]) << 8 | - unbase64(src[i + 3]); - // If MSB is set, input contains whitespace or is not valid base64. - if (v & 0x80808080) { - if (!base64_decode_group_slow(dst, dstlen, src, srclen, &i, &k)) - return k; - max_i = i + (srclen - i) / 4 * 4; // Align max_i again. - } else { - dst[k + 0] = ((v >> 22) & 0xFC) | ((v >> 20) & 0x03); - dst[k + 1] = ((v >> 12) & 0xF0) | ((v >> 10) & 0x0F); - dst[k + 2] = ((v >> 2) & 0xC0) | ((v >> 0) & 0x3F); - i += 4; - k += 3; - } - } - if (i < srclen && k < dstlen) { - base64_decode_group_slow(dst, dstlen, src, srclen, &i, &k); - } - return k; -} - - template <typename TypeName> size_t base64_decode(char* const dst, const size_t dstlen, const TypeName* const src, const size_t srclen) { |