changeset 22053:7ecd91f06169

imapc: Fix assert-crash if server doesn't send EXISTS reply to SELECT Fixes: Panic: file imapc-sync.c: line 477 (imapc_sync_index): assertion failed: (mbox->sync_fetch_first_uid == 1)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 18 May 2017 21:08:23 +0300
parents c641778fda28
children 412e15c438bc
files src/lib-storage/index/imapc/imapc-storage.c
diffstat 1 files changed, 34 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-storage.c	Thu May 18 20:18:24 2017 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Thu May 18 21:08:23 2017 +0300
@@ -540,21 +540,37 @@
 		 (mbox->box.flags & MAILBOX_FLAG_SAVEONLY) != 0);
 }
 
+static bool
+imapc_mailbox_verify_select(struct imapc_mailbox *mbox, const char **error_r)
+{
+	if (!mbox->exists_received)
+		*error_r = "EXISTS not received";
+	else
+		return TRUE;
+	return FALSE;
+}
+
 static void
 imapc_mailbox_reopen_callback(const struct imapc_command_reply *reply,
 			      void *context)
 {
 	struct imapc_mailbox *mbox = context;
+	const char *errmsg;
 
 	i_assert(mbox->storage->reopen_count > 0);
 	mbox->storage->reopen_count--;
 	mbox->selecting = FALSE;
-	if (reply->state != IMAPC_COMMAND_STATE_OK) {
-		const char *errmsg = t_strdup_printf(
-			"Reopening mailbox '%s' failed: %s",
-			mbox->box.name, reply->text_full);
-		imapc_client_mailbox_reconnect(mbox->client_box, errmsg);
+	if (reply->state != IMAPC_COMMAND_STATE_OK)
+		errmsg = reply->text_full;
+	else if (imapc_mailbox_verify_select(mbox, &errmsg))
+		errmsg = NULL;
+
+	if (errmsg != NULL) {
+		imapc_client_mailbox_reconnect(mbox->client_box,
+			t_strdup_printf("Reopening mailbox '%s' failed: %s",
+					mbox->box.name, errmsg));
 	}
+
 	imapc_client_stop(mbox->storage->client->client);
 }
 
@@ -578,6 +594,7 @@
 
 	mbox->initial_sync_done = FALSE;
 	mbox->selecting = TRUE;
+	mbox->exists_received = FALSE;
 
 	cmd = imapc_client_mailbox_cmd(mbox->client_box,
 				       imapc_mailbox_reopen_callback, mbox);
@@ -600,12 +617,20 @@
 			    void *context)
 {
 	struct imapc_open_context *ctx = context;
+	const char *error;
 
 	ctx->mbox->selecting = FALSE;
 	ctx->mbox->selected = TRUE;
-	if (reply->state == IMAPC_COMMAND_STATE_OK)
-		ctx->ret = 0;
-	else if (reply->state == IMAPC_COMMAND_STATE_NO) {
+	if (reply->state == IMAPC_COMMAND_STATE_OK) {
+		if (!imapc_mailbox_verify_select(ctx->mbox, &error)) {
+			mail_storage_set_critical(ctx->mbox->box.storage,
+				"imapc: Opening mailbox '%s' failed: %s",
+				ctx->mbox->box.name, error);
+			ctx->ret = -1;
+		} else {
+			ctx->ret = 0;
+		}
+	} else if (reply->state == IMAPC_COMMAND_STATE_NO) {
 		imapc_copy_error_from_reply(ctx->mbox->storage,
 					    MAIL_ERROR_NOTFOUND, reply);
 		ctx->ret = -1;
@@ -670,6 +695,7 @@
 	imapc_mailbox_get_extensions(mbox);
 
 	mbox->selecting = TRUE;
+	mbox->exists_received = FALSE;
 	ctx.mbox = mbox;
 	ctx.ret = -2;
 	cmd = imapc_client_mailbox_cmd(mbox->client_box,