From 0081ed0d90d302027ed4a53cb617c0179c246868 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Sun, 18 Jun 2017 11:14:05 +0300 Subject: [PATCH] imap: NOTIFY - Fix crash due to not hooking into commands correctly The pre/post hooks aren't always called immediately when commands are created. They're called only after the command input is being read. Call notify hooks explicitly now immediately when commands are allocated. Fixes a panic with for example: a notify set (selected (Messagenew (uid flags) MessageExpunge FlagChange) personal (MessageNew MessageExpunge FlagChange)) b select inbox c store 1 +flags \deleted d expunge e append inbox {10} Which crashed with: Panic: file imap-notify.c: line 397 (imap_notify_callback): assertion failed: (client->command_queue_size == 0) --- src/imap/imap-client.c | 2 ++ src/imap/imap-notify.c | 13 +++---------- src/imap/imap-notify.h | 1 + 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/imap/imap-client.c b/src/imap/imap-client.c index 0d1f098c84..b1dc803eb8 100644 --- a/src/imap/imap-client.c +++ b/src/imap/imap-client.c @@ -831,6 +831,8 @@ struct client_command_context *client_command_alloc(struct client *client) DLLIST_PREPEND(&client->command_queue, cmd); client->command_queue_size++; + + imap_client_notify_command_allocated(client); return cmd; } diff --git a/src/imap/imap-notify.c b/src/imap/imap-notify.c index 3b067f3412..37963db9bb 100644 --- a/src/imap/imap-notify.c +++ b/src/imap/imap-notify.c @@ -16,8 +16,6 @@ #define IMAP_NOTIFY_WATCH_ADD_DELAY_MSECS 1000 -static bool notify_hook_registered; - static int imap_notify_list(struct imap_notify_namespace *notify_ns, const struct mailbox_list_notify_rec *rec, enum mailbox_info_flags flags) @@ -451,16 +449,16 @@ void imap_client_notify_command_freed(struct client *client) } } -static void imap_notify_cmd_hook_pre(struct client_command_context *cmd) +void imap_client_notify_command_allocated(struct client *client) { - struct imap_notify_context *ctx = cmd->client->notify_ctx; + struct imap_notify_context *ctx = client->notify_ctx; if (ctx == NULL) return; /* remove mailbox watcher before starting any commands */ if (ctx->watching_mailbox) { - mailbox_notify_changes_stop(cmd->client->mailbox); + mailbox_notify_changes_stop(client->mailbox); ctx->watching_mailbox = FALSE; } if (ctx->to_watch != NULL) @@ -474,11 +472,6 @@ int imap_notify_begin(struct imap_notify_context *ctx) enum mailbox_list_notify_event notify_events; int ret = -1; - if (!notify_hook_registered) { - notify_hook_registered = TRUE; - command_hook_register(imap_notify_cmd_hook_pre, NULL); - } - array_foreach_modifiable(&ctx->namespaces, notify_ns) { notify_events = 0; array_foreach(¬ify_ns->mailboxes, notify_boxes) { diff --git a/src/imap/imap-notify.h b/src/imap/imap-notify.h index e917624406..936d622047 100644 --- a/src/imap/imap-notify.h +++ b/src/imap/imap-notify.h @@ -64,6 +64,7 @@ bool imap_notify_match_mailbox(struct imap_notify_namespace *notify_ns, int imap_client_notify_newmails(struct client *client); void imap_client_notify_finished(struct client *client); +void imap_client_notify_command_allocated(struct client *client); void imap_client_notify_command_freed(struct client *client); int imap_notify_begin(struct imap_notify_context *ctx);