dovecot-2.1: imapc: Avoid assert-crashing when replacing mail st...

dovecot at dovecot.org dovecot at dovecot.org
Wed Dec 14 13:00:49 EET 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/efb48f4e40a6
changeset: 13860:efb48f4e40a6
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Dec 14 13:00:05 2011 +0200
description:
imapc: Avoid assert-crashing when replacing mail stream with a new one.

diffstat:

 src/lib-storage/index/imapc/imapc-mail-fetch.c |   8 ++++----
 src/lib-storage/index/index-mail.c             |  24 +++++++++++++++++++++---
 2 files changed, 25 insertions(+), 7 deletions(-)

diffs (92 lines):

diff -r 96ce297561a0 -r efb48f4e40a6 src/lib-storage/index/imapc/imapc-mail-fetch.c
--- a/src/lib-storage/index/imapc/imapc-mail-fetch.c	Wed Dec 14 12:57:55 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-mail-fetch.c	Wed Dec 14 13:00:05 2011 +0200
@@ -277,13 +277,13 @@
 	if (imail->mail.v.istream_opened != NULL) {
 		if (imail->mail.v.istream_opened(_mail,
 						 &imail->data.stream) < 0) {
-			i_stream_unref(&imail->data.stream);
+			index_mail_close_streams(imail);
 			return;
 		}
 	} else if (have_body) {
 		ret = i_stream_get_size(imail->data.stream, TRUE, &size);
 		if (ret < 0) {
-			i_stream_unref(&imail->data.stream);
+			index_mail_close_streams(imail);
 			return;
 		}
 		i_assert(ret != 0);
@@ -295,7 +295,7 @@
 
 	imail->data.stream_has_only_header = !have_body;
 	if (index_mail_init_stream(imail, NULL, NULL, &input) < 0)
-		i_stream_unref(&imail->data.stream);
+		index_mail_close_streams(imail);
 }
 
 static void
@@ -311,7 +311,7 @@
 		if (!body)
 			return;
 		/* maybe the existing stream has no body. replace it. */
-		i_stream_unref(&imail->data.stream);
+		index_mail_close_streams(imail);
 		if (mail->fd != -1) {
 			if (close(mail->fd) < 0)
 				i_error("close(imapc mail) failed: %m");
diff -r 96ce297561a0 -r efb48f4e40a6 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Wed Dec 14 12:57:55 2011 +0200
+++ b/src/lib-storage/index/index-mail.c	Wed Dec 14 13:00:05 2011 +0200
@@ -1137,7 +1137,7 @@
 	}
 }
 
-void index_mail_close_streams(struct index_mail *mail)
+static void index_mail_close_streams_full(struct index_mail *mail, bool closing)
 {
 	struct index_mail_data *data = &mail->data;
 	struct message_part *parts;
@@ -1152,14 +1152,31 @@
 		i_stream_unref(&data->filter_stream);
 	if (data->stream != NULL) {
 		data->destroying_stream = TRUE;
+		if (!closing) {
+			/* we're replacing the stream with a new one. it's
+			   allowed to have references until the mail is closed
+			   (but we can't really check that) */
+			i_stream_unset_destroy_callback(data->stream);
+		}
 		i_stream_unref(&data->stream);
-		i_assert(!data->destroying_stream);
+		if (closing) {
+			/* there must be no references to the mail when the
+			   mail is being closed. */
+			i_assert(!mail->data.destroying_stream);
+		} else {
+			data->destroying_stream = FALSE;
+		}
 
 		data->initialized_wrapper_stream = FALSE;
 		data->destroy_callback_set = FALSE;
 	}
 }
 
+void index_mail_close_streams(struct index_mail *mail)
+{
+	index_mail_close_streams_full(mail, FALSE);
+}
+
 void index_mail_close(struct mail *_mail)
 {
 	struct index_mail *mail = (struct index_mail *)_mail;
@@ -1174,7 +1191,8 @@
 		index_mail_cache_dates(mail);
 	}
 
-	index_mail_close_streams(mail);
+	index_mail_close_streams_full(mail, TRUE);
+
 	if (mail->data.wanted_headers != NULL)
 		mailbox_header_lookup_unref(&mail->data.wanted_headers);
 }


More information about the dovecot-cvs mailing list