Skip to content

Commit

Permalink
imap: NOTIFY - Fix crash due to not hooking into commands correctly
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
sirainen committed Jun 18, 2017
1 parent 4693a58 commit 0081ed0
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/imap/imap-client.c
Expand Up @@ -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;
}

Expand Down
13 changes: 3 additions & 10 deletions src/imap/imap-notify.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/imap/imap-notify.h
Expand Up @@ -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);
Expand Down

0 comments on commit 0081ed0

Please sign in to comment.