From: compmaniak <6314398+compmaniak@users.noreply.github.com> Date: Wed, 30 Aug 2017 22:59:22 +0000 (+0300) Subject: lib: Preallocate output space for base64 encoding X-Git-Tag: 2.3.0.rc1~1119 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4e3be303f875ae203c6dec74b967ce868561851e;p=thirdparty%2Fdovecot%2Fcore.git lib: Preallocate output space for base64 encoding --- diff --git a/src/lib/base64.c b/src/lib/base64.c index d84014b7b2..ceaa1ff555 100644 --- a/src/lib/base64.c +++ b/src/lib/base64.c @@ -45,36 +45,38 @@ static const unsigned char b64dec[256] = { void base64_encode(const void *src, size_t src_size, buffer_t *dest) { + const size_t res_size = MAX_BASE64_ENCODED_SIZE(src_size); + unsigned char *start = buffer_append_space_unsafe(dest, res_size); + unsigned char *ptr = start; const unsigned char *src_c = src; - unsigned char tmp[4]; size_t src_pos; - for (src_pos = 0; src_size - src_pos > 2; src_pos += 3) { - tmp[0] = b64enc[src_c[src_pos] >> 2]; - tmp[1] = b64enc[((src_c[src_pos] & 0x03) << 4) | + for (src_pos = 0; src_size - src_pos > 2; src_pos += 3, ptr += 4) { + ptr[0] = b64enc[src_c[src_pos] >> 2]; + ptr[1] = b64enc[((src_c[src_pos] & 0x03) << 4) | (src_c[src_pos+1] >> 4)]; - tmp[2] = b64enc[((src_c[src_pos+1] & 0x0f) << 2) | + ptr[2] = b64enc[((src_c[src_pos+1] & 0x0f) << 2) | ((src_c[src_pos+2] & 0xc0) >> 6)]; - tmp[3] = b64enc[src_c[src_pos+2] & 0x3f]; - buffer_append(dest, tmp, 4); + ptr[3] = b64enc[src_c[src_pos+2] & 0x3f]; } + + i_assert(ptr <= start + res_size); + switch (src_size - src_pos) { case 0: break; case 1: - tmp[0] = b64enc[src_c[src_pos] >> 2]; - tmp[1] = b64enc[(src_c[src_pos] & 0x03) << 4]; - tmp[2] = '='; - tmp[3] = '='; - buffer_append(dest, tmp, 4); + ptr[0] = b64enc[src_c[src_pos] >> 2]; + ptr[1] = b64enc[(src_c[src_pos] & 0x03) << 4]; + ptr[2] = '='; + ptr[3] = '='; break; case 2: - tmp[0] = b64enc[src_c[src_pos] >> 2]; - tmp[1] = b64enc[((src_c[src_pos] & 0x03) << 4) | + ptr[0] = b64enc[src_c[src_pos] >> 2]; + ptr[1] = b64enc[((src_c[src_pos] & 0x03) << 4) | (src_c[src_pos+1] >> 4)]; - tmp[2] = b64enc[((src_c[src_pos+1] & 0x0f) << 2)]; - tmp[3] = '='; - buffer_append(dest, tmp, 4); + ptr[2] = b64enc[((src_c[src_pos+1] & 0x0f) << 2)]; + ptr[3] = '='; break; default: i_unreached();