diff -up dovecot-2.2.36/src/lib/array.h.CVE_2020_12100prereq dovecot-2.2.36/src/lib/array.h --- dovecot-2.2.36/src/lib/array.h.CVE_2020_12100prereq 2018-04-30 15:52:05.000000000 +0200 +++ dovecot-2.2.36/src/lib/array.h 2020-08-09 20:22:36.326347911 +0200 @@ -219,6 +219,15 @@ array_idx_i(const struct array *array, u i_assert(idx * array->element_size < array->buffer->used); return CONST_PTR_OFFSET(array->buffer->data, idx * array->element_size); } + +#define array_front(array) array_idx(array, 0) +#define array_front_modifiable(array) array_idx_modifiable(array, 0) +#define array_back(array) array_idx(array, array_count(array)-1) +#define array_back_modifiable(array) array_idx_modifiable(array, array_count(array)-1) +#define array_pop_back(array) array_delete(array, array_count(array)-1, 1); +#define array_push_back(array, item) array_append(array, (item), 1) +#define array_pop_front(array) array_delete(array, 0, 1) +#define array_push_front(array, item) array_insert(array, 0, (item), 1) #define array_idx(array, idx) \ ARRAY_TYPE_CAST_CONST(array)array_idx_i(&(array)->arr, idx) diff -up dovecot-2.2.36/src/lib/buffer.c.CVE_2020_12100prereq dovecot-2.2.36/src/lib/buffer.c --- dovecot-2.2.36/src/lib/buffer.c.CVE_2020_12100prereq 2020-08-09 20:22:57.566465762 +0200 +++ dovecot-2.2.36/src/lib/buffer.c 2020-08-09 20:22:57.580465840 +0200 @@ -148,6 +148,10 @@ void buffer_free(buffer_t **_buf) { struct real_buffer *buf = (struct real_buffer *)*_buf; + + if (buf == NULL) + return; + *_buf = NULL; if (buf->alloced) p_free(buf->pool, buf->w_buffer); diff -up dovecot-2.2.36/src/lib-mail/test-message-decoder.c.CVE_2020_12100prereq dovecot-2.2.36/src/lib-mail/test-message-decoder.c --- dovecot-2.2.36/src/lib-mail/test-message-decoder.c.CVE_2020_12100prereq 2018-04-30 15:52:05.000000000 +0200 +++ dovecot-2.2.36/src/lib-mail/test-message-decoder.c 2020-08-09 20:22:36.326347911 +0200 @@ -1,7 +1,8 @@ /* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */ #include "lib.h" -#include "buffer.h" +#include "str.h" +#include "istream.h" #include "charset-utf8.h" #include "message-parser.h" #include "message-header-decode.h" @@ -82,6 +83,66 @@ static void test_message_decoder(void) test_end(); } +static void test_message_decoder_multipart(void) +{ + static const char test_message_input[] = + "Content-Type: multipart/mixed; boundary=foo\n" + "\n" + "--foo\n" + "Content-Transfer-Encoding: quoted-printable\n" + "Content-Type: text/plain; charset=utf-8\n" + "\n" + "p=C3=A4iv=C3=A4=C3=A4\n" + "\n" + "--foo\n" + "Content-Transfer-Encoding: base64\n" + "Content-Type: text/plain; charset=utf-8\n" + "\n" + "ecO2dMOkIHZhYW4uCg== ignored\n" + "--foo\n" + "Content-Transfer-Encoding: base64\n" + "Content-Type: text/plain; charset=utf-8\n" + "\n" + "?garbage\n" + "--foo--\n"; + struct message_parser_ctx *parser; + struct message_decoder_context *decoder; + struct message_part *parts; + struct message_block input, output; + struct istream *istream; + string_t *str_out = t_str_new(20); + int ret; + + test_begin("message decoder multipart"); + + istream = test_istream_create(test_message_input); + parser = message_parser_init(pool_datastack_create(), istream, 0, 0); + decoder = message_decoder_init(NULL, 0); + + test_istream_set_allow_eof(istream, FALSE); + for (size_t i = 0; i < sizeof(test_message_input); i++) { + if (i == sizeof(test_message_input)-1) + test_istream_set_allow_eof(istream, TRUE); + test_istream_set_size(istream, i); + while ((ret = message_parser_parse_next_block(parser, &input)) > 0) { + if (message_decoder_decode_next_block(decoder, &input, &output) && + output.hdr == NULL && output.size > 0) + str_append_data(str_out, output.data, output.size); + } + if (i == sizeof(test_message_input)-1) + test_assert(ret == -1); + else + test_assert(ret == 0); + } + /* NOTE: qp-decoder decoder changes \n into \r\n */ + test_assert_strcmp(str_c(str_out), "p\xC3\xA4iv\xC3\xA4\xC3\xA4\r\ny\xC3\xB6t\xC3\xA4 vaan.\n"); + + message_decoder_deinit(&decoder); + message_parser_deinit(&parser, &parts); + i_stream_unref(&istream); + test_end(); +} + static void test_message_decoder_current_content_type(void) { struct message_decoder_context *ctx; @@ -149,6 +210,7 @@ int main(void) { static void (*test_functions[])(void) = { test_message_decoder, + //test_message_decoder_multipart, test_message_decoder_current_content_type, NULL };