From: Stephan Bosch Date: Wed, 15 May 2019 13:36:18 +0000 (+0200) Subject: lib: base64 - Add support for encoding without padding. X-Git-Tag: 2.3.8~126 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=84cd2444ba9bfd19e0417cf5ee164337fd4f50ce;p=thirdparty%2Fdovecot%2Fcore.git lib: base64 - Add support for encoding without padding. --- diff --git a/src/lib/base64.c b/src/lib/base64.c index 53a10dc368..fb8eeace98 100644 --- a/src/lib/base64.c +++ b/src/lib/base64.c @@ -11,11 +11,25 @@ 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(); diff --git a/src/lib/base64.h b/src/lib/base64.h index e9c2922e2a..751adf10bf 100644 --- a/src/lib/base64.h +++ b/src/lib/base64.h @@ -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 { diff --git a/src/lib/test-base64.c b/src/lib/test-base64.c index 0bd54a571c..6e944694f3 100644 --- a/src/lib/test-base64.c +++ b/src/lib/test-base64.c @@ -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 =