1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
From 6001e4b48c5a23735eb9c4ca9a187a175fd1a1da Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Thu, 2 Jul 2020 17:31:19 +0300
Subject: [PATCH] lib-mail: Fix handling trailing "--" in MIME boundaries
Broken by 5b8ec27fae941d06516c30476dcf4820c6d200ab
---
src/lib-mail/message-parser.c | 14 ++++++++----
src/lib-mail/test-message-parser.c | 46 ++++++++++++++++++++++++++++++++++++++
2 files changed, 56 insertions(+), 4 deletions(-)
Index: dovecot/src/lib-mail/message-parser.c
===================================================================
--- dovecot.orig/src/lib-mail/message-parser.c
+++ dovecot/src/lib-mail/message-parser.c
@@ -19,7 +19,7 @@ static int parse_next_body_to_eof(struct
static struct message_boundary *
boundary_find(struct message_boundary *boundaries,
- const unsigned char *data, size_t len)
+ const unsigned char *data, size_t len, bool trailing_dashes)
{
struct message_boundary *best = NULL;
@@ -33,7 +33,11 @@ boundary_find(struct message_boundary *b
memcmp(boundaries->boundary, data, boundaries->len) == 0 &&
(best == NULL || best->len < boundaries->len)) {
best = boundaries;
- if (best->len == len) {
+ /* If we see "foo--", it could either mean that there
+ is a boundary named "foo" that ends now or there's
+ a boundary "foo--" which continues. */
+ if (best->len == len ||
+ (best->len == len-2 && trailing_dashes)) {
/* This is exactly the wanted boundary. There
can't be a better one. */
break;
@@ -261,6 +265,7 @@ boundary_line_find(struct message_parser
return 0;
}
size_t find_size = size;
+ bool trailing_dashes = FALSE;
if (lf_pos != NULL) {
find_size = lf_pos - data;
@@ -268,11 +273,12 @@ boundary_line_find(struct message_parser
find_size--;
if (find_size > 2 && data[find_size-1] == '-' &&
data[find_size-2] == '-')
- find_size -= 2;
+ trailing_dashes = TRUE;
} else if (find_size > BOUNDARY_END_MAX_LEN)
find_size = BOUNDARY_END_MAX_LEN;
- *boundary_r = boundary_find(ctx->boundaries, data, find_size);
+ *boundary_r = boundary_find(ctx->boundaries, data, find_size,
+ trailing_dashes);
if (*boundary_r == NULL)
return -1;
Index: dovecot/src/lib-mail/test-message-parser.c
===================================================================
--- dovecot.orig/src/lib-mail/test-message-parser.c
+++ dovecot/src/lib-mail/test-message-parser.c
@@ -534,6 +534,51 @@ static const char input_msg[] =
test_end();
}
+static void test_message_parser_trailing_dashes(void)
+{
+static const char input_msg[] =
+"Content-Type: multipart/mixed; boundary=\"a--\"\n"
+"\n"
+"--a--\n"
+"Content-Type: multipart/mixed; boundary=\"a----\"\n"
+"\n"
+"--a----\n"
+"Content-Type: text/plain\n"
+"\n"
+"body\n"
+"--a------\n"
+"Content-Type: text/html\n"
+"\n"
+"body2\n"
+"--a----";
+ struct message_parser_ctx *parser;
+ struct istream *input;
+ struct message_part *parts;
+ struct message_block block;
+ pool_t pool;
+ int ret;
+
+ test_begin("message parser trailing dashes");
+ pool = pool_alloconly_create("message parser", 10240);
+ input = test_istream_create(input_msg);
+
+ parser = message_parser_init(pool, input, &set_empty);
+ while ((ret = message_parser_parse_next_block(parser, &block)) > 0) ;
+ test_assert(ret < 0);
+ message_parser_deinit(&parser, &parts);
+
+ test_assert(parts->children_count == 2);
+ test_assert(parts->children->next == NULL);
+ test_assert(parts->children->children_count == 1);
+ test_assert(parts->children->children->next == NULL);
+ test_assert(parts->children->children->children_count == 0);
+
+ test_parsed_parts(input, parts);
+ i_stream_unref(&input);
+ pool_unref(&pool);
+ test_end();
+}
+
static void test_message_parser_continuing_mime_boundary(void)
{
static const char input_msg[] =
@@ -1097,6 +1142,7 @@ int main(void)
test_message_parser_empty_multipart,
test_message_parser_duplicate_mime_boundary,
test_message_parser_garbage_suffix_mime_boundary,
+ test_message_parser_trailing_dashes,
test_message_parser_continuing_mime_boundary,
test_message_parser_continuing_truncated_mime_boundary,
test_message_parser_continuing_mime_boundary_reverse,
|