Skip to content

Commit 21b5821

Browse files
rscharfegitster
authored andcommitted
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 <[email protected]> Signed-off-by: René Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 39bb692 commit 21b5821

File tree

1 file changed

+12
-23
lines changed

1 file changed

+12
-23
lines changed

imap-send.c

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,6 @@ static void imap_warn(const char *, ...);
6868

6969
static char *next_arg(char **);
7070

71-
static int nfvasprintf(char **strp, const char *fmt, va_list ap)
72-
{
73-
int len;
74-
char tmp[8192];
75-
76-
len = vsnprintf(tmp, sizeof(tmp), fmt, ap);
77-
if (len < 0)
78-
die("Fatal: Out of memory");
79-
if (len >= sizeof(tmp))
80-
die("imap command overflow!");
81-
*strp = xmemdupz(tmp, len);
82-
return len;
83-
}
84-
8571
struct imap_server_conf {
8672
const char *name;
8773
const char *tunnel;
@@ -503,11 +489,11 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
503489
{
504490
struct imap *imap = ctx->imap;
505491
struct imap_cmd *cmd;
506-
int n, bufl;
507-
char buf[1024];
492+
int n;
493+
struct strbuf buf = STRBUF_INIT;
508494

509495
cmd = xmalloc(sizeof(struct imap_cmd));
510-
nfvasprintf(&cmd->cmd, fmt, ap);
496+
cmd->cmd = xstrvfmt(fmt, ap);
511497
cmd->tag = ++imap->nexttag;
512498

513499
if (cb)
@@ -519,27 +505,30 @@ static struct imap_cmd *issue_imap_cmd(struct imap_store *ctx,
519505
get_cmd_result(ctx, NULL);
520506

521507
if (!cmd->cb.data)
522-
bufl = xsnprintf(buf, sizeof(buf), "%d %s\r\n", cmd->tag, cmd->cmd);
508+
strbuf_addf(&buf, "%d %s\r\n", cmd->tag, cmd->cmd);
523509
else
524-
bufl = xsnprintf(buf, sizeof(buf), "%d %s{%d%s}\r\n",
525-
cmd->tag, cmd->cmd, cmd->cb.dlen,
526-
CAP(LITERALPLUS) ? "+" : "");
510+
strbuf_addf(&buf, "%d %s{%d%s}\r\n", cmd->tag, cmd->cmd,
511+
cmd->cb.dlen, CAP(LITERALPLUS) ? "+" : "");
512+
if (buf.len > INT_MAX)
513+
die("imap command overflow!");
527514

528515
if (0 < verbosity) {
529516
if (imap->num_in_progress)
530517
printf("(%d in progress) ", imap->num_in_progress);
531518
if (!starts_with(cmd->cmd, "LOGIN"))
532-
printf(">>> %s", buf);
519+
printf(">>> %s", buf.buf);
533520
else
534521
printf(">>> %d LOGIN <user> <pass>\n", cmd->tag);
535522
}
536-
if (socket_write(&imap->buf.sock, buf, bufl) != bufl) {
523+
if (socket_write(&imap->buf.sock, buf.buf, buf.len) != buf.len) {
537524
free(cmd->cmd);
538525
free(cmd);
539526
if (cb)
540527
free(cb->data);
528+
strbuf_release(&buf);
541529
return NULL;
542530
}
531+
strbuf_release(&buf);
543532
if (cmd->cb.data) {
544533
if (CAP(LITERALPLUS)) {
545534
n = socket_write(&imap->buf.sock, cmd->cb.data, cmd->cb.dlen);

0 commit comments

Comments
 (0)