changeset 20891:d2872ec409ec

global: Handle broken Content-Type headers consistently. 1) Only the first Content-Type header is used. (Simpler than using the last.) 2) Invalid Content-Types are parsed as far as we can. This is mainly to make sure they aren't treated as missing Content-Types, which could cause them to become text/plain.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Mon, 10 Oct 2016 20:38:31 +0300
parents d946c76fb3d4
children 111ca700d6bd
files src/lib-mail/istream-attachment-extractor.c src/lib-mail/message-decoder.c src/lib-mail/message-parser.c src/lib-mail/message-search.c src/plugins/fts/fts-build-mail.c
diffstat 5 files changed, 22 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-mail/istream-attachment-extractor.c	Mon Oct 10 20:24:41 2016 +0300
+++ b/src/lib-mail/istream-attachment-extractor.c	Mon Oct 10 20:38:31 2016 +0300
@@ -77,16 +77,16 @@
 	struct rfc822_parser_context parser;
 	string_t *content_type;
 
+	if (astream->part.content_type != NULL)
+		return;
+
 	rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
 	rfc822_skip_lwsp(&parser);
 
 	T_BEGIN {
 		content_type = t_str_new(64);
-		if (rfc822_parse_content_type(&parser, content_type) >= 0) {
-			i_free(astream->part.content_type);
-			astream->part.content_type =
-				i_strdup(str_c(content_type));
-		}
+		(void)rfc822_parse_content_type(&parser, content_type);
+		astream->part.content_type = i_strdup(str_c(content_type));
 	} T_END;
 }
 
--- a/src/lib-mail/message-decoder.c	Mon Oct 10 20:24:41 2016 +0300
+++ b/src/lib-mail/message-decoder.c	Mon Oct 10 20:38:31 2016 +0300
@@ -127,6 +127,7 @@
 	struct rfc822_parser_context parser;
 	const char *const *results;
 	string_t *str;
+	int ret;
 
 	if (ctx->content_type != NULL)
 		return;
@@ -134,9 +135,10 @@
 	rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
 	rfc822_skip_lwsp(&parser);
 	str = t_str_new(64);
-	if (rfc822_parse_content_type(&parser, str) < 0)
+	ret = rfc822_parse_content_type(&parser, str);
+	ctx->content_type = i_strdup(str_c(str));
+	if (ret < 0)
 		return;
-	ctx->content_type = i_strdup(str_c(str));
 
 	rfc2231_parse(&parser, &results);
 	for (; *results != NULL; results += 2) {
--- a/src/lib-mail/message-parser.c	Mon Oct 10 20:24:41 2016 +0300
+++ b/src/lib-mail/message-parser.c	Mon Oct 10 20:38:31 2016 +0300
@@ -474,6 +474,7 @@
 	struct rfc822_parser_context parser;
 	const char *const *results;
 	string_t *content_type;
+	int ret;
 
 	if (ctx->part_seen_content_type)
 		return;
@@ -483,8 +484,7 @@
 	rfc822_skip_lwsp(&parser);
 
 	content_type = t_str_new(64);
-	if (rfc822_parse_content_type(&parser, content_type) < 0)
-		return;
+	ret = rfc822_parse_content_type(&parser, content_type);
 
 	if (strcasecmp(str_c(content_type), "message/rfc822") == 0)
 		ctx->part->flags |= MESSAGE_PART_FLAG_MESSAGE_RFC822;
@@ -499,6 +499,8 @@
 			ctx->part->flags |= MESSAGE_PART_FLAG_MULTIPART_DIGEST;
 	}
 
+	if (ret < 0)
+		return;
 	if ((ctx->part->flags & MESSAGE_PART_FLAG_MULTIPART) == 0 ||
 	    ctx->last_boundary != NULL)
 		return;
--- a/src/lib-mail/message-search.c	Mon Oct 10 20:24:41 2016 +0300
+++ b/src/lib-mail/message-search.c	Mon Oct 10 20:38:31 2016 +0300
@@ -57,11 +57,10 @@
 	rfc822_skip_lwsp(&parser);
 
 	content_type = t_str_new(64);
-	if (rfc822_parse_content_type(&parser, content_type) >= 0) {
-		ctx->content_type_text =
-			strncasecmp(str_c(content_type), "text/", 5) == 0 ||
-			strncasecmp(str_c(content_type), "message/", 8) == 0;
-	}
+	(void)rfc822_parse_content_type(&parser, content_type);
+	ctx->content_type_text =
+		strncasecmp(str_c(content_type), "text/", 5) == 0 ||
+		strncasecmp(str_c(content_type), "message/", 8) == 0;
 }
 
 static void handle_header(struct message_search_context *ctx,
--- a/src/plugins/fts/fts-build-mail.c	Mon Oct 10 20:24:41 2016 +0300
+++ b/src/plugins/fts/fts-build-mail.c	Mon Oct 10 20:38:31 2016 +0300
@@ -45,16 +45,16 @@
 	struct rfc822_parser_context parser;
 	string_t *content_type;
 
+	if (ctx->content_type != NULL)
+		return;
+
 	rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
 	rfc822_skip_lwsp(&parser);
 
 	T_BEGIN {
 		content_type = t_str_new(64);
-		if (rfc822_parse_content_type(&parser, content_type) >= 0) {
-			i_free(ctx->content_type);
-			ctx->content_type =
-				str_lcase(i_strdup(str_c(content_type)));
-		}
+		(void)rfc822_parse_content_type(&parser, content_type);
+		ctx->content_type = str_lcase(i_strdup(str_c(content_type)));
 	} T_END;
 }