]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imap: Avoid wrongly assert-crashing in client_check_command_hangs()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 7 Sep 2016 08:52:00 +0000 (11:52 +0300)
committerGitLab <gitlab@git.dovecot.net>
Thu, 8 Sep 2016 17:25:32 +0000 (20:25 +0300)
Fixes assert:

Panic: file imap-client.c: line 837 (client_check_command_hangs): assertion failed: (client->io != NULL)

src/imap/imap-client.c

index 33277888577bcf656b75ac9e2026f6a2e333d150..806e662c428d5ede8e32f9e5d3093b6053a6b3b1 100644 (file)
@@ -853,7 +853,14 @@ static void client_check_command_hangs(struct client *client)
        for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next) {
                switch (cmd->state) {
                case CLIENT_COMMAND_STATE_WAIT_INPUT:
-                       i_assert(client->io != NULL);
+                       /* We need to be reading input for this command.
+                          However, if there is already an output lock for
+                          another command we'll wait for it to finish first.
+                          This is needed because if there are any literals
+                          we'd need to send "+ OK" responses. */
+                       i_assert(client->io != NULL ||
+                                (client->output_cmd_lock != NULL &&
+                                 client->output_cmd_lock != client->input_lock));
                        unfinished_count++;
                        break;
                case CLIENT_COMMAND_STATE_WAIT_OUTPUT:
@@ -1056,6 +1063,8 @@ static bool client_handle_next_command(struct client *client, bool *remove_io_r)
        if (client->input_lock != NULL) {
                if (client->input_lock->state ==
                    CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY ||
+                   /* we can't send literal "+ OK" replies if output is
+                      locked by another command. */
                    (client->output_cmd_lock != NULL &&
                     client->output_cmd_lock != client->input_lock)) {
                        *remove_io_r = TRUE;