dovecot-2.0: imap: Fixed infinite loop / memory eating with SEAR...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Feb 22 12:00:16 EET 2011
details: http://hg.dovecot.org/dovecot-2.0/rev/3053befe6a64
changeset: 12616:3053befe6a64
user: Timo Sirainen <tss at iki.fi>
date: Tue Feb 22 11:59:57 2011 +0200
description:
imap: Fixed infinite loop / memory eating with SEARCHRES + pipelining $.
If SEARCH RETURN (SAVE) command was running long enough so that Dovecot
started executing the next command, and if that command used $ in
messageset, Dovecot went into infinite function recursion.
diffstat:
src/imap/imap-client.c | 20 ++++++++++++++++----
src/imap/imap-client.h | 1 +
2 files changed, 17 insertions(+), 4 deletions(-)
diffs (72 lines):
diff -r 324f9ca60539 -r 3053befe6a64 src/imap/imap-client.c
--- a/src/imap/imap-client.c Tue Feb 22 11:14:31 2011 +0200
+++ b/src/imap/imap-client.c Tue Feb 22 11:59:57 2011 +0200
@@ -432,7 +432,7 @@
return NULL;
}
-static bool client_command_check_ambiguity(struct client_command_context *cmd)
+static bool client_command_is_ambiguous(struct client_command_context *cmd)
{
enum command_flags flags;
enum client_command_state max_state =
@@ -443,6 +443,17 @@
!imap_sync_is_allowed(cmd->client))
return TRUE;
+ if (cmd->search_save_result_used) {
+ /* if there are pending commands that update the search
+ save result, wait */
+ struct client_command_context *old_cmd = cmd->next;
+
+ for (; old_cmd != NULL; old_cmd = old_cmd->next) {
+ if (old_cmd->search_save_result)
+ return TRUE;
+ }
+ }
+
if ((cmd->cmd_flags & COMMAND_FLAG_BREAKS_MAILBOX) ==
COMMAND_FLAG_BREAKS_MAILBOX) {
/* there must be no other command running that uses the
@@ -578,11 +589,11 @@
/* the command is waiting for existing ambiguity causing
commands to finish. */
- if (client_command_check_ambiguity(cmd)) {
+ if (client_command_is_ambiguous(cmd)) {
/* we could be waiting for existing sync to finish */
if (!cmd_sync_delayed(client))
return;
- if (client_command_check_ambiguity(cmd))
+ if (client_command_is_ambiguous(cmd))
return;
}
cmd->state = CLIENT_COMMAND_STATE_WAIT_INPUT;
@@ -690,7 +701,7 @@
} else if ((command = command_find(cmd->name)) != NULL) {
cmd->func = command->func;
cmd->cmd_flags = command->flags;
- if (client_command_check_ambiguity(cmd)) {
+ if (client_command_is_ambiguous(cmd)) {
/* do nothing until existing commands are finished */
i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
@@ -907,6 +918,7 @@
i_assert(cmd->state == CLIENT_COMMAND_STATE_WAIT_INPUT);
cmd->client->input_lock = cmd;
cmd->state = CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY;
+ cmd->search_save_result_used = TRUE;
io_remove(&cmd->client->io);
return TRUE;
}
diff -r 324f9ca60539 -r 3053befe6a64 src/imap/imap-client.h
--- a/src/imap/imap-client.h Tue Feb 22 11:14:31 2011 +0200
+++ b/src/imap/imap-client.h Tue Feb 22 11:59:57 2011 +0200
@@ -82,6 +82,7 @@
unsigned int cancel:1; /* command is wanted to be cancelled */
unsigned int param_error:1;
unsigned int search_save_result:1; /* search result is being updated */
+ unsigned int search_save_result_used:1; /* command uses search save */
unsigned int temp_executed:1; /* temporary execution state tracking */
};
More information about the dovecot-cvs
mailing list