From: Timo Sirainen Date: Tue, 25 May 2021 17:03:53 +0000 (+0300) Subject: lib-mail: Add MESSAGE_PART_FLAG_OVERFLOW to MIME parts that reached parsing limits X-Git-Tag: 2.3.16~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2d676b00071d031e523b48eda7e4cfd810d23189;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: Add MESSAGE_PART_FLAG_OVERFLOW to MIME parts that reached parsing limits This allows callers to find out which MIME parts were properly parsed. --- diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c index 6e45fe2caf..9a9c9a3515 100644 --- a/src/lib-mail/message-parser.c +++ b/src/lib-mail/message-parser.c @@ -253,6 +253,7 @@ boundary_line_find(struct message_parser_ctx *ctx, if (ctx->total_parts_count >= ctx->max_total_mime_parts) { /* can't add any more MIME parts. just stop trying to find more boundaries. */ + ctx->part->flags |= MESSAGE_PART_FLAG_OVERFLOW; return -1; } @@ -597,6 +598,7 @@ static int parse_next_header(struct message_parser_ctx *ctx, parse_next_body_multipart_init(ctx); ctx->multipart = TRUE; } else { + part->flags |= MESSAGE_PART_FLAG_OVERFLOW; part->flags &= ENUM_NEGATE(MESSAGE_PART_FLAG_MULTIPART); } } @@ -702,11 +704,19 @@ static int parse_next_header(struct message_parser_ctx *ctx, i_assert(ctx->last_boundary == NULL); ctx->multipart = FALSE; ctx->parse_next_block = parse_next_body_to_boundary; - } else if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) != 0 && - !parse_too_many_nested_mime_parts(ctx) && + } else if ((part->flags & MESSAGE_PART_FLAG_MESSAGE_RFC822) == 0) { + /* Not message/rfc822 */ + if (ctx->boundaries != NULL) + ctx->parse_next_block = parse_next_body_to_boundary; + else + ctx->parse_next_block = parse_next_body_to_eof; + } else if (!parse_too_many_nested_mime_parts(ctx) && ctx->total_parts_count < ctx->max_total_mime_parts) { + /* message/rfc822 - not reached MIME part limits yet */ ctx->parse_next_block = parse_next_body_message_rfc822_init; } else { + /* message/rfc822 - already reached MIME part limits */ + part->flags |= MESSAGE_PART_FLAG_OVERFLOW; part->flags &= ENUM_NEGATE(MESSAGE_PART_FLAG_MESSAGE_RFC822); if (ctx->boundaries != NULL) ctx->parse_next_block = parse_next_body_to_boundary; diff --git a/src/lib-mail/message-part.h b/src/lib-mail/message-part.h index 7f6afa3748..d8f99ab5d7 100644 --- a/src/lib-mail/message-part.h +++ b/src/lib-mail/message-part.h @@ -21,7 +21,11 @@ enum message_part_flags { MESSAGE_PART_FLAG_HAS_NULS = 0x20, /* Mime-Version header exists. */ - MESSAGE_PART_FLAG_IS_MIME = 0x40 + MESSAGE_PART_FLAG_IS_MIME = 0x40, + /* Message parsing was aborted because there were too many MIME parts. + This MIME part points to a blob which wasn't actually parsed to + see if it would contain further MIME parts. */ + MESSAGE_PART_FLAG_OVERFLOW = 0x80, }; struct message_part { diff --git a/src/lib-mail/test-message-parser.c b/src/lib-mail/test-message-parser.c index c4e117afc7..663bfe8c5a 100644 --- a/src/lib-mail/test-message-parser.c +++ b/src/lib-mail/test-message-parser.c @@ -965,7 +965,8 @@ static const char input_msg[] = part = parts->children; test_assert(part->children_count == 0); - test_assert(part->flags == MESSAGE_PART_FLAG_IS_MIME); + test_assert(part->flags == (MESSAGE_PART_FLAG_IS_MIME | + MESSAGE_PART_FLAG_OVERFLOW)); test_assert(part->header_size.lines == 2); test_assert(part->header_size.physical_size == 45); test_assert(part->header_size.virtual_size == 45+2); @@ -1029,7 +1030,8 @@ static const char input_msg[] = part = parts->children; test_assert(part->children_count == 0); - test_assert(part->flags == MESSAGE_PART_FLAG_IS_MIME); + test_assert(part->flags == (MESSAGE_PART_FLAG_IS_MIME | + MESSAGE_PART_FLAG_OVERFLOW)); test_assert(part->header_size.lines == 2); test_assert(part->header_size.physical_size == 30); test_assert(part->header_size.virtual_size == 30+2); @@ -1113,7 +1115,9 @@ static const char input_msg[] = part = parts->children->children->next; test_assert(part->children_count == 0); - test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_IS_MIME)); + test_assert(part->flags == (MESSAGE_PART_FLAG_TEXT | + MESSAGE_PART_FLAG_IS_MIME | + MESSAGE_PART_FLAG_OVERFLOW)); test_assert(part->header_size.lines == 2); test_assert(part->header_size.physical_size == 26); test_assert(part->header_size.virtual_size == 26+2); @@ -1194,7 +1198,8 @@ static const char input_msg[] = part = parts->children->children; test_assert(part->children_count == 0); - test_assert(part->flags == MESSAGE_PART_FLAG_IS_MIME); + test_assert(part->flags == (MESSAGE_PART_FLAG_IS_MIME | + MESSAGE_PART_FLAG_OVERFLOW)); test_assert(part->header_size.lines == 2); test_assert(part->header_size.physical_size == 30); test_assert(part->header_size.virtual_size == 30+2); @@ -1277,7 +1282,9 @@ static const char *const input_msgs[] = { part = part->children; test_assert_idx(part->children_count == 0, i); - test_assert_idx(part->flags == 72, i); + test_assert_idx(part->flags == (MESSAGE_PART_FLAG_TEXT | + MESSAGE_PART_FLAG_IS_MIME | + MESSAGE_PART_FLAG_OVERFLOW), i); test_assert_idx(part->header_size.lines == 2, i); test_assert_idx(part->header_size.physical_size == 26, i); test_assert_idx(part->header_size.virtual_size == 28, i);