Mercurial > dovecot > core-2.2
changeset 19116:73acc7075146
imap: NOTIFY (SUBSCRIPTIONS) assert-crashed when subscriptions hadn't been refreshed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 07 Sep 2015 23:08:44 +0300 |
parents | bb80b907a116 |
children | fa979ccfa34c |
files | src/imap/cmd-notify.c src/imap/imap-notify.h |
diffstat | 2 files changed, 28 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/cmd-notify.c Mon Sep 07 22:35:30 2015 +0300 +++ b/src/imap/cmd-notify.c Mon Sep 07 23:08:44 2015 +0300 @@ -206,11 +206,34 @@ } } +static int +imap_notify_refresh_subscriptions(struct client_command_context *cmd, + struct imap_notify_context *ctx) +{ + struct mailbox_list_iterate_context *iter; + struct mail_namespace *ns; + + if (!ctx->have_subscriptions) + return 0; + + /* make sure subscriptions are refreshed at least once */ + for (ns = ctx->client->user->namespaces; ns != NULL; ns = ns->next) { + iter = mailbox_list_iter_init(ns->list, "*", MAILBOX_LIST_ITER_SELECT_SUBSCRIBED); + (void)mailbox_list_iter_next(iter); + if (mailbox_list_iter_deinit(&iter) < 0) { + client_send_list_error(cmd, ns->list); + return -1; + } + } + return 0; +} + static void cmd_notify_add_subscribed(struct imap_notify_context *ctx, enum imap_notify_event events) { struct mail_namespace *ns; + ctx->have_subscriptions = TRUE; for (ns = ctx->client->user->namespaces; ns != NULL; ns = ns->next) { cmd_notify_add_mailbox(ctx, ns, "", IMAP_NOTIFY_TYPE_SUBSCRIBED, events); @@ -523,6 +546,10 @@ "NO [NOTIFICATIONOVERFLOW] Too many mailbox names"); pool_unref(&pool); return TRUE; + } else if (imap_notify_refresh_subscriptions(cmd, ctx) < 0) { + /* tagline already sent */ + pool_unref(&pool); + return TRUE; } else if (imap_notify_begin(ctx) < 0) { client_send_tagline(cmd, "NO [NOTIFICATIONOVERFLOW] NOTIFY not supported for these mailboxes.");
--- a/src/imap/imap-notify.h Mon Sep 07 22:35:30 2015 +0300 +++ b/src/imap/imap-notify.h Mon Sep 07 23:08:44 2015 +0300 @@ -49,6 +49,7 @@ struct imap_fetch_context *fetch_ctx; struct timeout *to_watch; + unsigned int have_subscriptions:1; unsigned int selected_set:1; unsigned int selected_immediate_expunges:1; unsigned int send_immediate_status:1;