44#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55
66#include " util.h"
7+ #include " base64-inl.h"
78
89#include < cstddef>
910#include < cstdint>
@@ -20,6 +21,8 @@ static inline constexpr size_t base64_decoded_size_fast(size_t size) {
2021 return size > 1 ? (size / 4 ) * 3 + (size % 4 + 1 ) / 2 : 0 ;
2122}
2223
24+ inline uint32_t ReadUint32BE (const unsigned char * p);
25+
2326template <typename TypeName>
2427size_t base64_decoded_size (const TypeName* src, size_t size) {
2528 // 1-byte input cannot be decoded
@@ -34,81 +37,6 @@ size_t base64_decoded_size(const TypeName* src, size_t size) {
3437 return base64_decoded_size_fast (size);
3538}
3639
37-
38- extern const int8_t unbase64_table[256 ];
39-
40-
41- inline static int8_t unbase64 (uint8_t x) {
42- return unbase64_table[x];
43- }
44-
45-
46- template <typename TypeName>
47- bool base64_decode_group_slow (char * const dst, const size_t dstlen,
48- const TypeName* const src, const size_t srclen,
49- size_t * const i, size_t * const k) {
50- uint8_t hi;
51- uint8_t lo;
52- #define V (expr ) \
53- for (;;) { \
54- const uint8_t c = src[*i]; \
55- lo = unbase64 (c); \
56- *i += 1 ; \
57- if (lo < 64 ) \
58- break ; /* Legal character. */ \
59- if (c == ' =' || *i >= srclen) \
60- return false ; /* Stop decoding. */ \
61- } \
62- expr; \
63- if (*i >= srclen) \
64- return false ; \
65- if (*k >= dstlen) \
66- return false ; \
67- hi = lo;
68- V (/* Nothing. */ );
69- V (dst[(*k)++] = ((hi & 0x3F ) << 2 ) | ((lo & 0x30 ) >> 4 ));
70- V (dst[(*k)++] = ((hi & 0x0F ) << 4 ) | ((lo & 0x3C ) >> 2 ));
71- V (dst[(*k)++] = ((hi & 0x03 ) << 6 ) | ((lo & 0x3F ) >> 0 ));
72- #undef V
73- return true ; // Continue decoding.
74- }
75-
76-
77- template <typename TypeName>
78- size_t base64_decode_fast (char * const dst, const size_t dstlen,
79- const TypeName* const src, const size_t srclen,
80- const size_t decoded_size) {
81- const size_t available = dstlen < decoded_size ? dstlen : decoded_size;
82- const size_t max_k = available / 3 * 3 ;
83- size_t max_i = srclen / 4 * 4 ;
84- size_t i = 0 ;
85- size_t k = 0 ;
86- while (i < max_i && k < max_k) {
87- const uint32_t v =
88- unbase64 (src[i + 0 ]) << 24 |
89- unbase64 (src[i + 1 ]) << 16 |
90- unbase64 (src[i + 2 ]) << 8 |
91- unbase64 (src[i + 3 ]);
92- // If MSB is set, input contains whitespace or is not valid base64.
93- if (v & 0x80808080 ) {
94- if (!base64_decode_group_slow (dst, dstlen, src, srclen, &i, &k))
95- return k;
96- max_i = i + (srclen - i) / 4 * 4 ; // Align max_i again.
97- } else {
98- dst[k + 0 ] = ((v >> 22 ) & 0xFC ) | ((v >> 20 ) & 0x03 );
99- dst[k + 1 ] = ((v >> 12 ) & 0xF0 ) | ((v >> 10 ) & 0x0F );
100- dst[k + 2 ] = ((v >> 2 ) & 0xC0 ) | ((v >> 0 ) & 0x3F );
101- i += 4 ;
102- k += 3 ;
103- }
104- }
105- if (i < srclen && k < dstlen) {
106- base64_decode_group_slow (dst, dstlen, src, srclen, &i, &k);
107- }
108- return k;
109- }
110-
111-
11240template <typename TypeName>
11341size_t base64_decode (char * const dst, const size_t dstlen,
11442 const TypeName* const src, const size_t srclen) {
0 commit comments