dovecot-2.2: imap: Fixed handling FETCH BINARY for broken content.

dovecot at dovecot.org dovecot at dovecot.org
Tue Dec 4 13:02:58 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/9c1791d1834f
changeset: 15451:9c1791d1834f
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Dec 04 13:02:22 2012 +0200
description:
imap: Fixed handling FETCH BINARY for broken content.

diffstat:

 src/doveadm/doveadm-mail.c                |   1 +
 src/imap/cmd-fetch.c                      |   4 ++--
 src/imap/imap-commands-util.c             |   1 +
 src/imap/imap-fetch-body.c                |  23 ++++++++++++++++++-----
 src/lib-storage/index/index-mail-binary.c |  16 ++++++++++++----
 src/lib-storage/mail-error.h              |   5 ++++-
 6 files changed, 38 insertions(+), 12 deletions(-)

diffs (131 lines):

diff -r 4d382ee358fb -r 9c1791d1834f src/doveadm/doveadm-mail.c
--- a/src/doveadm/doveadm-mail.c	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/doveadm/doveadm-mail.c	Tue Dec 04 13:02:22 2012 +0200
@@ -48,6 +48,7 @@
 	case MAIL_ERROR_NOTPOSSIBLE:
 	case MAIL_ERROR_EXISTS:
 	case MAIL_ERROR_CONVERSION:
+	case MAIL_ERROR_INVALIDDATA:
 		exit_code = DOVEADM_EX_NOTPOSSIBLE;
 		break;
 	case MAIL_ERROR_PARAMS:
diff -r 4d382ee358fb -r 9c1791d1834f src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/imap/cmd-fetch.c	Tue Dec 04 13:02:22 2012 +0200
@@ -195,8 +195,8 @@
 		errstr = mailbox_get_last_error(cmd->client->mailbox, &error);
 		if (error == MAIL_ERROR_CONVERSION) {
 			/* BINARY found unsupported Content-Transfer-Encoding */
-			tagged_reply = "NO ["IMAP_RESP_CODE_UNKNOWN_CTE"] "
-				"Unknown Content-Transfer-Encoding.";
+			tagged_reply = t_strdup_printf(
+				"NO ["IMAP_RESP_CODE_UNKNOWN_CTE"] %s", errstr);
 		} else {
 			/* We never want to reply NO to FETCH requests,
 			   BYE is preferrable (see imap-ml for reasons). */
diff -r 4d382ee358fb -r 9c1791d1834f src/imap/imap-commands-util.c
--- a/src/imap/imap-commands-util.c	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/imap/imap-commands-util.c	Tue Dec 04 13:02:22 2012 +0200
@@ -137,6 +137,7 @@
 		resp_code = IMAP_RESP_CODE_INUSE;
 		break;
 	case MAIL_ERROR_CONVERSION:
+	case MAIL_ERROR_INVALIDDATA:
 		break;
 	}
 	if (resp_code == NULL || *error_string == '[')
diff -r 4d382ee358fb -r 9c1791d1834f src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/imap/imap-fetch-body.c	Tue Dec 04 13:02:22 2012 +0200
@@ -135,8 +135,16 @@
 		return 1;
 	}
 
-	if (imap_msgpart_open(mail, body->msgpart, &result) < 0)
-		return -1;
+	if (imap_msgpart_open(mail, body->msgpart, &result) < 0) {
+		if (!body->binary ||
+		    mailbox_get_last_mail_error(mail->box) != MAIL_ERROR_INVALIDDATA)
+			return -1;
+		/* tried to do BINARY fetch for a MIME part with broken
+		   content */
+		str = get_prefix(&ctx->state, body, (uoff_t)-1, FALSE);
+		o_stream_nsend(ctx->client->output, str_data(str), str_len(str));
+		return 1;
+	}
 	ctx->state.cur_input = result.input;
 	ctx->state.cur_size = result.size;
 	ctx->state.cur_size_field = result.size_field;
@@ -161,8 +169,13 @@
 		return 1;
 	}
 
-	if (imap_msgpart_size(mail, body->msgpart, &size) < 0)
-		return -1;
+	if (imap_msgpart_size(mail, body->msgpart, &size) < 0) {
+		if (mailbox_get_last_mail_error(mail->box) != MAIL_ERROR_INVALIDDATA)
+			return -1;
+		/* tried to do BINARY.SIZE fetch for a MIME part with broken
+		   content */
+		size = 0;
+	}
 
 	str = t_str_new(128);
 	if (ctx->state.cur_first)
@@ -406,7 +419,7 @@
 	ctx->name = p_strdup(ctx->pool, get_body_name(body));
 	if (body->binary_size) {
 		imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT,
-				       "NIL", fetch_binary_size, body);
+				       "0", fetch_binary_size, body);
 	} else {
 		imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT,
 				       "NIL", fetch_body_msgpart, body);
diff -r 4d382ee358fb -r 9c1791d1834f src/lib-storage/index/index-mail-binary.c
--- a/src/lib-storage/index/index-mail-binary.c	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/lib-storage/index/index-mail-binary.c	Tue Dec 04 13:02:22 2012 +0200
@@ -119,7 +119,8 @@
 
 	if (cte == MESSAGE_CTE_UNKNOWN) {
 		mail_storage_set_error(ctx->mail->box->storage,
-				       MAIL_ERROR_CONVERSION, "Unknown CTE");
+				       MAIL_ERROR_CONVERSION,
+				       "Unknown Content-Transfer-Encoding.");
 		return -1;
 	}
 
@@ -385,9 +386,16 @@
 		"<binary stream of mailbox %s UID %u>",
 		_mail->box->vname, _mail->uid));
 	if (blocks_count_lines(&ctx, cache->input) < 0) {
-		mail_storage_set_critical(_mail->box->storage,
-					  "read(%s) failed: %m",
-					  i_stream_get_name(cache->input));
+		if (cache->input->stream_errno == EINVAL) {
+			/* MIME part contains invalid data */
+			mail_storage_set_error(_mail->box->storage,
+					       MAIL_ERROR_INVALIDDATA,
+					       "Invalid data in MIME part");
+		} else {
+			mail_storage_set_critical(_mail->box->storage,
+				"read(%s) failed: %m",
+				i_stream_get_name(cache->input));
+		}
 		mail_storage_free_binary_cache(_mail->box->storage);
 		binary_streams_free(&ctx);
 		return -1;
diff -r 4d382ee358fb -r 9c1791d1834f src/lib-storage/mail-error.h
--- a/src/lib-storage/mail-error.h	Tue Dec 04 11:40:35 2012 +0200
+++ b/src/lib-storage/mail-error.h	Tue Dec 04 13:02:22 2012 +0200
@@ -43,7 +43,10 @@
 	MAIL_ERROR_INUSE,
 	/* Can't do the requested data conversion (e.g. IMAP BINARY's
 	   UNKNOWN-CTE code) */
-	MAIL_ERROR_CONVERSION
+	MAIL_ERROR_CONVERSION,
+	/* Can't do the requested data conversion because the original data
+	   isn't valid. */
+	MAIL_ERROR_INVALIDDATA
 };
 
 /* Convert errno to mail_error and an error string. Returns TRUE if successful,


More information about the dovecot-cvs mailing list