]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: NOTIFY - Fix crash due to not hooking into commands correctly
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 18 Jun 2017 08:14:05 +0000 (11:14 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Mon, 19 Jun 2017 07:59:29 +0000 (10:59 +0300)
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
src/imap/imap-notify.c
src/imap/imap-notify.h

index 48aef887530056ef7854fdf1808baa2358dbbfcf..f9d998c4450d0ad78692e4d8e29052b310f06cf7 100644 (file)
@@ -833,6 +833,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;
 }
 
index 3b067f341294c03f91a78a63de2237833ffdc0e1..37963db9bb85ebb9e014675b4cc62e9014f4b3c4 100644 (file)
@@ -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(&notify_ns->mailboxes, notify_boxes) {
index 46e7b2b21c123a7ff794c9a528d732a35cbb668c..eaa9f2934999b7ab23a519248ccc499a12c78cd6 100644 (file)
@@ -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);