From: Kevin McCarthy Date: Wed, 19 Jul 2017 21:04:39 +0000 (-0700) Subject: Change imap_cmd_start() to return OK when the cmd_queue is finished. (closes #3956) X-Git-Tag: neomutt-20170907~54^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35f8d69a2056c1a6dc3445e8bedf7197081fae25;p=neomutt Change imap_cmd_start() to return OK when the cmd_queue is finished. (closes #3956) Some response handlers can end up recursively calling imap_cmd_start(), processing all the command completions. If the outer call was an imap_exec(), this would result in the loop never being terminated (or just blocking reading a server that has already finished all the commands). Change the callers that are simply using it to read a response, without having called cmd_start(), to check for IMAP_CMD_OK instead. Currently this is just the open connection function. --- diff --git a/imap/command.c b/imap/command.c index dac5d5fcd..902a9ff14 100644 --- a/imap/command.c +++ b/imap/command.c @@ -911,8 +911,17 @@ int imap_cmd_step(struct ImapData *idata) if (idata->buf[0] == '+') return IMAP_CMD_RESPOND; - /* look for tagged command completions */ - rc = IMAP_CMD_CONTINUE; + /* Look for tagged command completions. + * + * Some response handlers can end up recursively calling + * imap_cmd_step() and end up handling all tagged command + * completions. + * (e.g. FETCH->set_flag->set_header_color->~h pattern match.) + * + * Other callers don't even create an idata->cmds entry. + * + * For both these cases, we default to returning OK */ + rc = IMAP_CMD_OK; c = idata->lastcmd; do { diff --git a/imap/imap.c b/imap/imap.c index b906ca283..048a4a295 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -454,7 +454,7 @@ int imap_open_connection(struct ImapData *idata) idata->state = IMAP_CONNECTED; - if (imap_cmd_step(idata) != IMAP_CMD_CONTINUE) + if (imap_cmd_step(idata) != IMAP_CMD_OK) { imap_close_connection(idata); return -1;