handle tagged BAD [TOOBIG] server responses

some servers consider attempts to APPEND too big messages to be BAD
commands, rather than just NO-worthy ones. so just pretend that we did
in fact get a NO, and carry on.

this was tested with gmail. if we run into servers that don't send the
expected response code, we will need to relax the condition.
This commit is contained in:
Oswald Buddenhagen 2021-12-26 20:05:33 +01:00
parent 5e5c7fb508
commit 4ae0159132

View File

@ -156,7 +156,7 @@ union imap_store {
char wait_check; /* Don't report success until subsequent CHECK success. */ \ char wait_check; /* Don't report success until subsequent CHECK success. */ \
char to_trash; /* we are storing to trash, not current. */ \ char to_trash; /* we are storing to trash, not current. */ \
char create; /* create the mailbox if we get an error which suggests so. */ \ char create; /* create the mailbox if we get an error which suggests so. */ \
char failok; /* Don't complain about NO response. */ \ char failok; /* Don't complain about NO (@1) / BAD (@2) response. */ \
} param; } param;
struct imap_cmd { struct imap_cmd {
@ -1718,8 +1718,13 @@ imap_socket_read( void *aux )
if (cmdp->param.failok) // SELECT if (cmdp->param.failok) // SELECT
goto doresp; goto doresp;
} else /*if (!strcmp( "BAD", arg ))*/ { } else /*if (!strcmp( "BAD", arg ))*/ {
if (cmdp->param.failok == 2 && cmd && starts_with_upper( cmd, -1, "[TOOBIG]", 8 )) { // APPEND
resp = RESP_NO;
// Fall through - we still complain
} else {
resp = RESP_CANCEL; resp = RESP_CANCEL;
} }
}
error( "IMAP command '%s' returned an error: %s %s\n", error( "IMAP command '%s' returned an error: %s %s\n",
starts_with( cmdp->cmd, -1, "LOGIN", 5 ) ? starts_with( cmdp->cmd, -1, "LOGIN", 5 ) ?
"LOGIN <user> <pass>" : "LOGIN <user> <pass>" :
@ -3233,6 +3238,7 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int to_trash,
ctx->buffer_mem += data->len; ctx->buffer_mem += data->len;
cmd->param.data_len = data->len; cmd->param.data_len = data->len;
cmd->param.data = data->data; cmd->param.data = data->data;
cmd->param.failok = 2;
if (to_trash) { if (to_trash) {
cmd->param.create = 1; cmd->param.create = 1;