Mercurial > dovecot > core-2.2
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,