Mercurial > dovecot > original-hg > dovecot-1.1
changeset 8308:f9c44dd6dc8b 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:57:10 -0400 |
parents | 2e24a3d8fcd9 |
children | 2b557de3fb25 |
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:22:30 2009 -0400 +++ b/src/imap/client.c Mon Jun 15 21:57:10 2009 -0400 @@ -378,6 +378,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:22:30 2009 -0400 +++ b/src/imap/commands.c Mon Jun 15 21:57:10 2009 -0400 @@ -41,7 +41,8 @@ #define IMAP4REV1_COMMANDS_COUNT N_ELEMENTS(imap4rev1_commands) static const struct command imap_ext_commands[] = { - { "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:22:30 2009 -0400 +++ b/src/imap/commands.h Mon Jun 15 21:57:10 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:22:30 2009 -0400 +++ b/src/imap/imap-sync.c Mon Jun 15 21:57:10 2009 -0400 @@ -203,6 +203,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) @@ -404,9 +416,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:22:30 2009 -0400 +++ b/src/imap/imap-sync.h Mon Jun 15 21:57:10 2009 -0400 @@ -16,6 +16,9 @@ int imap_sync_deinit(struct imap_sync_context *ctx); 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,