imap-send: increase command size limit
nfvasprintf() has a 8KB limit, but it's not relevant, as its result is combined with other strings and added to a 1KB buffer by its caller. That 1KB limit is not mentioned in RFC 9051, which specifies IMAP. While 1KB is plenty for user names, passwords and mailbox names, there's no point in limiting our commands like that. Call xstrvfmt() instead of open-coding it and use strbuf to format the command to send, as we need its length. Fail hard if it exceeds INT_MAX, because socket_write() can't take more than that. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
39bb692152
commit
21b5821acd
35
imap-send.c
35
imap-send.c
@ -68,20 +68,6 @@ static void imap_warn(const char *, ...);
|
||||
|
||||
static char *next_arg(char **);
|
||||
|
||||
static int nfvasprintf(char **strp, const char *fmt, va_list ap)
|
||||
{
|
||||
int len;
|
||||
char tmp[8192];
|
||||
|
||||
len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
|
||||
if (len < 0)
|
||||
die("Fatal: Out of memory");
|
||||
if (len >= sizeof(tmp))
|
||||
die("imap command overflow!");
|
||||
*strp = xmemdupz(tmp, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
struct imap_server_conf {
|
||||
const char *name;
|
||||
const char *tunnel;
|
||||
@ -503,11 +489,11 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
|
||||
{
|
||||
struct imap *imap = ctx->imap;
|
||||
struct imap_cmd *cmd;
|
||||
int n, bufl;
|
||||
char buf[1024];
|
||||
int n;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
cmd = xmalloc(sizeof(struct imap_cmd));
|
||||
nfvasprintf(&cmd->cmd, fmt, ap);
|
||||
cmd->cmd = xstrvfmt(fmt, ap);
|
||||
cmd->tag = ++imap->nexttag;
|
||||
|
||||
if (cb)
|
||||
@ -519,27 +505,30 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
|
||||
get_cmd_result(ctx, NULL);
|
||||
|
||||
if (!cmd->cb.data)
|
||||
bufl = xsnprintf(buf, sizeof(buf), "%d %s\r\n", cmd->tag, cmd->cmd);
|
||||
strbuf_addf(&buf, "%d %s\r\n", cmd->tag, cmd->cmd);
|
||||
else
|
||||
bufl = xsnprintf(buf, sizeof(buf), "%d %s{%d%s}\r\n",
|
||||
cmd->tag, cmd->cmd, cmd->cb.dlen,
|
||||
CAP(LITERALPLUS) ? "+" : "");
|
||||
strbuf_addf(&buf, "%d %s{%d%s}\r\n", cmd->tag, cmd->cmd,
|
||||
cmd->cb.dlen, CAP(LITERALPLUS) ? "+" : "");
|
||||
if (buf.len > INT_MAX)
|
||||
die("imap command overflow!");
|
||||
|
||||
if (0 < verbosity) {
|
||||
if (imap->num_in_progress)
|
||||
printf("(%d in progress) ", imap->num_in_progress);
|
||||
if (!starts_with(cmd->cmd, "LOGIN"))
|
||||
printf(">>> %s", buf);
|
||||
printf(">>> %s", buf.buf);
|
||||
else
|
||||
printf(">>> %d LOGIN <user> <pass>\n", cmd->tag);
|
||||
}
|
||||
if (socket_write(&imap->buf.sock, buf, bufl) != bufl) {
|
||||
if (socket_write(&imap->buf.sock, buf.buf, buf.len) != buf.len) {
|
||||
free(cmd->cmd);
|
||||
free(cmd);
|
||||
if (cb)
|
||||
free(cb->data);
|
||||
strbuf_release(&buf);
|
||||
return NULL;
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
if (cmd->cb.data) {
|
||||
if (CAP(LITERALPLUS)) {
|
||||
n = socket_write(&imap->buf.sock, cmd->cb.data, cmd->cb.dlen);
|
||||
|
Reference in New Issue
Block a user