Mercurial > dovecot > original-hg > dovecot-1.2
changeset 9136:ef7c0c3b1976 HEAD
IMAP: Don't crash if IDLE command is pipelined after a long-running UID FETCH or UID SEARCH.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 15 Jun 2009 21:56:22 -0400 |
parents | 39c234ab0b21 |
children | 1d343780e009 |
files | src/imap/client.c src/imap/commands.c src/imap/commands.h src/imap/imap-sync.c src/imap/imap-sync.h |
diffstat | 5 files changed, 26 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/imap/client.c Mon Jun 15 21:43:37 2009 -0400 +++ b/src/imap/client.c Mon Jun 15 21:56:22 2009 -0400 @@ -391,6 +391,10 @@ CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY; bool broken_client = FALSE; + if ((cmd->cmd_flags & COMMAND_FLAG_REQUIRES_SYNC) != 0 && + !imap_sync_is_allowed(cmd->client)) + return TRUE; + if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_MAILBOX) == COMMAND_FLAG_BREAKS_MAILBOX) { /* there must be no other command running that uses the
--- a/src/imap/commands.c Mon Jun 15 21:43:37 2009 -0400 +++ b/src/imap/commands.c Mon Jun 15 21:56:22 2009 -0400 @@ -44,7 +44,8 @@ { "CANCELUPDATE", cmd_cancelupdate,0 }, { "ENABLE", cmd_enable, 0 }, { "ID", cmd_id, 0 }, - { "IDLE", cmd_idle, COMMAND_FLAG_BREAKS_SEQS }, + { "IDLE", cmd_idle, COMMAND_FLAG_BREAKS_SEQS | + COMMAND_FLAG_REQUIRES_SYNC }, { "NAMESPACE", cmd_namespace, 0 }, { "SORT", cmd_sort, COMMAND_FLAG_USES_SEQS }, { "THREAD", cmd_thread, COMMAND_FLAG_USES_SEQS },
--- a/src/imap/commands.h Mon Jun 15 21:43:37 2009 -0400 +++ b/src/imap/commands.h Mon Jun 15 21:56:22 2009 -0400 @@ -20,7 +20,10 @@ /* Command uses selected mailbox */ COMMAND_FLAG_USES_MAILBOX = COMMAND_FLAG_BREAKS_MAILBOX | - COMMAND_FLAG_USES_SEQS + COMMAND_FLAG_USES_SEQS, + + /* Command requires mailbox syncing before it can do its job. */ + COMMAND_FLAG_REQUIRES_SYNC = 0x08 }; struct command {
--- a/src/imap/imap-sync.c Mon Jun 15 21:43:37 2009 -0400 +++ b/src/imap/imap-sync.c Mon Jun 15 21:56:22 2009 -0400 @@ -475,6 +475,18 @@ return ret; } +bool imap_sync_is_allowed(struct client *client) +{ + if (client->syncing) + return FALSE; + + if (client->mailbox != NULL && + mailbox_transaction_get_count(client->mailbox) > 0) + return FALSE; + + return TRUE; +} + static bool cmd_finish_sync(struct client_command_context *cmd) { if (cmd->sync->callback != NULL) @@ -676,9 +688,7 @@ return FALSE; } - if (client->syncing || - (client->mailbox != NULL && - mailbox_transaction_get_count(client->mailbox) > 0)) { + if (!imap_sync_is_allowed(client)) { /* wait until mailbox can be synced */ return cmd_sync_drop_fast(client); }
--- a/src/imap/imap-sync.h Mon Jun 15 21:43:37 2009 -0400 +++ b/src/imap/imap-sync.h Mon Jun 15 21:56:22 2009 -0400 @@ -17,6 +17,9 @@ struct client_command_context *sync_cmd); int imap_sync_more(struct imap_sync_context *ctx); +/* Returns TRUE if syncing would be allowed currently. */ +bool imap_sync_is_allowed(struct client *client); + bool cmd_sync(struct client_command_context *cmd, enum mailbox_sync_flags flags, enum imap_sync_flags imap_flags, const char *tagline); bool cmd_sync_callback(struct client_command_context *cmd,