]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Preallocate output space for base64 encoding
authorcompmaniak <6314398+compmaniak@users.noreply.github.com>
Wed, 30 Aug 2017 22:59:22 +0000 (01:59 +0300)
committerJosef 'Jeff' Sipek <jeff.sipek@dovecot.fi>
Thu, 31 Aug 2017 10:40:40 +0000 (13:40 +0300)
src/lib/base64.c

index d84014b7b223da3570c4cb9c7b284677c7fea7a2..ceaa1ff555a657b753c1f59f0cf99b016ca63d99 100644 (file)
@@ -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();