forked from nodejs/node
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src: create helper for reading Uint32BE
Fixes: nodejs#34827 PR-URL: nodejs#34944 Reviewed-By: Anna Henningsen <anna@addaleax.net>
- Loading branch information
Showing
5 changed files
with
110 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#ifndef SRC_BASE64_INL_H_ | ||
#define SRC_BASE64_INL_H_ | ||
|
||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#include "util.h" | ||
|
||
namespace node { | ||
|
||
extern const int8_t unbase64_table[256]; | ||
|
||
|
||
inline static int8_t unbase64(uint8_t x) { | ||
return unbase64_table[x]; | ||
} | ||
|
||
|
||
inline uint32_t ReadUint32BE(const unsigned char* p) { | ||
return static_cast<uint32_t>(p[0] << 24U) | | ||
static_cast<uint32_t>(p[1] << 16U) | | ||
static_cast<uint32_t>(p[2] << 8U) | | ||
static_cast<uint32_t>(p[3]); | ||
} | ||
|
||
|
||
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 unsigned char txt[] = { | ||
static_cast<unsigned char>(unbase64(src[i + 0])), | ||
static_cast<unsigned char>(unbase64(src[i + 1])), | ||
static_cast<unsigned char>(unbase64(src[i + 2])), | ||
static_cast<unsigned char>(unbase64(src[i + 3])), | ||
}; | ||
|
||
const uint32_t v = ReadUint32BE(txt); | ||
// 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; | ||
} | ||
|
||
} // namespace node | ||
|
||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#endif // SRC_BASE64_INL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters