]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-imap: Fix writing BODYSTRUCTURE for truncated multipart/digest part
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 18 Nov 2020 19:22:45 +0000 (21:22 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Wed, 2 Dec 2020 07:31:44 +0000 (07:31 +0000)
Fixes error while parsing BODYSTRUCTURE:
message_part message/rfc822 flag doesn't match lines in BODYSTRUCTURE

src/lib-imap/imap-bodystructure.c
src/lib-imap/test-imap-bodystructure.c

index bfb6e64197b69ca759b1793882357b43fe0dc272..5d2e5a3a84ab5ccb564292f44e2adb014e21989a 100644 (file)
@@ -161,6 +161,14 @@ static bool part_is_truncated(const struct message_part *part)
                           MESSAGE_PART_FLAG_MULTIPART. */
                        return TRUE;
                }
+       } else {
+               /* No Content-Type */
+               if (part->parent != NULL &&
+                   (part->parent->flags & MESSAGE_PART_FLAG_MULTIPART_DIGEST) != 0) {
+                       /* Parent is MESSAGE_PART_FLAG_MULTIPART_DIGEST
+                          (so this should have been message/rfc822). */
+                       return TRUE;
+               }
        }
        return FALSE;
 }
@@ -195,6 +203,7 @@ static void part_write_body(const struct message_part *part,
                        str_append_c(str, ' ');
                        imap_append_string(str, data->content_subtype);
                }
+               i_assert(text == ((part->flags & MESSAGE_PART_FLAG_TEXT) != 0));
        }
 
        /* ("content type param key" "value" ...) */
index 2118907e78303eaa3bb955a2011bb8eb7c60cf8c..0f70cb00354286a2e2ea90012f0318e3bfcbded8 100644 (file)
@@ -381,13 +381,14 @@ static const unsigned int normalize_tests_count = N_ELEMENTS(normalize_tests);
 
 static struct message_part *
 msg_parse(pool_t pool, const char *message, unsigned int max_nested_mime_parts,
-         bool parse_bodystructure)
+         unsigned int max_total_mime_parts, bool parse_bodystructure)
 {
        const struct message_parser_settings parser_set = {
                .hdr_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP |
                        MESSAGE_HEADER_PARSER_FLAG_DROP_CR,
                .flags = MESSAGE_PARSER_FLAG_SKIP_BODY_BLOCK,
                .max_nested_mime_parts = max_nested_mime_parts,
+               .max_total_mime_parts = max_total_mime_parts,
        };
        struct message_parser_ctx *parser;
        struct istream *input;
@@ -421,7 +422,7 @@ static void test_imap_bodystructure_write(void)
                pool_t pool = pool_alloconly_create("imap bodystructure write", 1024);
 
                test_begin(t_strdup_printf("imap bodystructure write [%u]", i));
-               parts = msg_parse(pool, test->message, 0, TRUE);
+               parts = msg_parse(pool, test->message, 0, 0, TRUE);
 
                imap_bodystructure_write(parts, str, TRUE);
                test_assert(strcmp(str_c(str), test->bodystructure) == 0);
@@ -448,7 +449,7 @@ static void test_imap_bodystructure_parse(void)
                pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
 
                test_begin(t_strdup_printf("imap bodystructure parser [%u]", i));
-               parts = msg_parse(pool, test->message, 0, FALSE);
+               parts = msg_parse(pool, test->message, 0, 0, FALSE);
 
                test_assert(imap_body_parse_from_bodystructure(test->bodystructure,
                                                                     str, &error) == 0);
@@ -515,7 +516,7 @@ static void test_imap_bodystructure_normalize(void)
                pool_t pool = pool_alloconly_create("imap bodystructure parse", 1024);
 
                test_begin(t_strdup_printf("imap bodystructure normalize [%u]", i));
-               parts = msg_parse(pool, test->message, 0, FALSE);
+               parts = msg_parse(pool, test->message, 0, 0, FALSE);
 
                ret = imap_bodystructure_parse(test->input,
                                                           pool, parts, &error);
@@ -538,6 +539,7 @@ static const struct {
        const char *input;
        const char *bodystructure;
        unsigned int max_depth;
+       unsigned int max_total;
 } truncation_tests[] = {
        {
                .input = "Content-Type: message/rfc822\n"
@@ -571,6 +573,23 @@ static const struct {
                .bodystructure = "(\"application\" \"octet-stream\" (\"boundary\" \"2\") NIL NIL \"7bit\" 63 NIL NIL NIL NIL) \"mixed\" (\"boundary\" \"1\") NIL NIL NIL",
                .max_depth = 2,
        },
+       {
+               .input = "Content-Type: multipart/digest; boundary=1\n"
+                       "\n"
+                       "--1\n"
+                       "\n"
+                       "Subject: hdr1\n"
+                       "\n"
+                       "body1\n"
+                       "--1\n"
+                       "\n"
+                       "Subject: hdr2\n"
+                       "\n"
+                       "body2\n",
+               .bodystructure = "(\"application\" \"octet-stream\" NIL NIL NIL \"7bit\" 55 NIL NIL NIL NIL) \"digest\" (\"boundary\" \"1\") NIL NIL NIL",
+               .max_total = 2,
+       },
+
 };
 
 static void test_imap_bodystructure_truncation(void)
@@ -590,6 +609,7 @@ static void test_imap_bodystructure_truncation(void)
 
                parts = msg_parse(pool, truncation_tests[i].input,
                                  truncation_tests[i].max_depth,
+                                 truncation_tests[i].max_total,
                                  TRUE);
 
                /* write out BODYSTRUCTURE and serialize message_parts */