]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: base64 - Add support for encoding without padding.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 15 May 2019 13:36:18 +0000 (15:36 +0200)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Tue, 10 Sep 2019 07:02:27 +0000 (10:02 +0300)
src/lib/base64.c
src/lib/base64.h
src/lib/test-base64.c

index 53a10dc368cfceac420196b05b6806596e8d6794..fb8eeace98c7fd5dfd640e47d542bdadc8fc658e 100644 (file)
 off_t base64_get_full_encoded_size(struct base64_encoder *enc, off_t src_size)
 {
        bool crlf = HAS_ALL_BITS(enc->flags, BASE64_ENCODE_FLAG_CRLF);
+       bool no_padding = HAS_ALL_BITS(enc->flags,
+                                      BASE64_ENCODE_FLAG_NO_PADDING);
        off_t out_size;
        off_t newlines;
 
        /* calculate size of encoded data */
        out_size = MAX_BASE64_ENCODED_SIZE(src_size);
+       if (no_padding) {
+               switch (src_size % 3) {
+               case 0:
+                       break;
+               case 1:
+                       out_size -= 2;
+                       break;
+               case 2:
+                       out_size -= 1;
+                       break;
+               }
+       }
 
        /* newline between each full line */
        newlines = (out_size / enc->max_line_len) - 1;
@@ -337,6 +351,7 @@ bool base64_encode_finish(struct base64_encoder *enc, buffer_t *dest)
        const struct base64_scheme *b64 = enc->b64;
        const char *b64enc = b64->encmap;
        bool crlf = HAS_ALL_BITS(enc->flags, BASE64_ENCODE_FLAG_CRLF);
+       bool padding = HAS_NO_BITS(enc->flags, BASE64_ENCODE_FLAG_NO_PADDING);
        unsigned char *ptr, *end;
        size_t dst_avail, line_avail, write;
        unsigned char w_buf[9];
@@ -364,15 +379,21 @@ bool base64_encode_finish(struct base64_encoder *enc, buffer_t *dest)
        case 0:
                break;
        case 1:
-               w_buf[w_buf_len + 0] = b64enc[enc->buf];
-               w_buf[w_buf_len + 1] =  '=';
-               w_buf[w_buf_len + 2] =  '=';
-               w_buf_len += 3;
+               w_buf[w_buf_len] = b64enc[enc->buf];
+               w_buf_len ++;
+               if (padding) {
+                       w_buf[w_buf_len + 0] =  '=';
+                       w_buf[w_buf_len + 1] =  '=';
+                       w_buf_len += 2;
+               }
                break;
        case 2:
-               w_buf[w_buf_len + 0] = b64enc[enc->buf];
-               w_buf[w_buf_len + 1] =  '=';
-               w_buf_len += 2;
+               w_buf[w_buf_len] = b64enc[enc->buf];
+               w_buf_len++;
+               if (padding) {
+                       w_buf[w_buf_len + 0] =  '=';
+                       w_buf_len++;
+               }
                break;
        default:
                i_unreached();
index e9c2922e2ac7a436efaeed95eba457e3be18d305..751adf10bf654e4d2251b389120274de5fdffefe 100644 (file)
@@ -24,6 +24,8 @@ struct base64_scheme {
 enum base64_encode_flags {
        /* Use CRLF instead of the default LF as line ending. */
        BASE64_ENCODE_FLAG_CRLF                 = BIT(0),
+       /* Encode no padding at the end of the data. */
+       BASE64_ENCODE_FLAG_NO_PADDING           = BIT(1),
 };
 
 struct base64_encoder {
index 0bd54a571cf72e0e0b9067ecf81b1813355ae2f2..6e944694f39dc12eefb3443b3629a4286e13c93f 100644 (file)
@@ -263,6 +263,12 @@ tests_base64_encode_lowlevel[] = {
                .input = "hello world",
                .output = "aGVsbG8gd29ybGQ=",
        },
+       {
+               .scheme = &base64_scheme,
+               .flags = BASE64_ENCODE_FLAG_NO_PADDING,
+               .input = "hello world",
+               .output = "aGVsbG8gd29ybGQ",
+       },
        {
                .scheme = &base64_scheme,
                .input = "foo barits",
@@ -273,6 +279,12 @@ tests_base64_encode_lowlevel[] = {
                .input = "foo barits",
                .output = "Zm9vIGJhcml0cw==",
        },
+       {
+               .scheme = &base64_scheme,
+               .flags = BASE64_ENCODE_FLAG_NO_PADDING,
+               .input = "foo barits",
+               .output = "Zm9vIGJhcml0cw",
+       },
        {
                .scheme = &base64_scheme,
                .input = "just niin",
@@ -283,6 +295,12 @@ tests_base64_encode_lowlevel[] = {
                .input = "just niin",
                .output = "anVzdCBuaWlu",
        },
+       {
+               .scheme = &base64_scheme,
+               .flags = BASE64_ENCODE_FLAG_NO_PADDING,
+               .input = "just niin",
+               .output = "anVzdCBuaWlu",
+       },
        {
                .scheme = &base64_scheme,
                .input =