imap-send: fix leaking memory in `imap_server_conf`

We never free any of the config strings that we populate into the
`struct imap_server_conf`. Fix this by creating a common exit path where
we can free resources.

While at it, drop the unused member `imap_server_conf::name`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Patrick Steinhardt 2024-06-07 08:39:22 +02:00 committed by Junio C Hamano
parent cea1ff7f1f
commit 6d1f198f34
1 changed files with 41 additions and 22 deletions

View File

@ -69,7 +69,6 @@ static void imap_warn(const char *, ...);
static char *next_arg(char **); static char *next_arg(char **);


struct imap_server_conf { struct imap_server_conf {
const char *name;
char *tunnel; char *tunnel;
char *host; char *host;
int port; int port;
@ -1300,23 +1299,28 @@ static int git_imap_config(const char *var, const char *val,
{ {
struct imap_server_conf *cfg = cb; struct imap_server_conf *cfg = cb;


if (!strcmp("imap.sslverify", var)) if (!strcmp("imap.sslverify", var)) {
cfg->ssl_verify = git_config_bool(var, val); cfg->ssl_verify = git_config_bool(var, val);
else if (!strcmp("imap.preformattedhtml", var)) } else if (!strcmp("imap.preformattedhtml", var)) {
cfg->use_html = git_config_bool(var, val); cfg->use_html = git_config_bool(var, val);
else if (!strcmp("imap.folder", var)) } else if (!strcmp("imap.folder", var)) {
FREE_AND_NULL(cfg->folder);
return git_config_string(&cfg->folder, var, val); return git_config_string(&cfg->folder, var, val);
else if (!strcmp("imap.user", var)) } else if (!strcmp("imap.user", var)) {
FREE_AND_NULL(cfg->folder);
return git_config_string(&cfg->user, var, val); return git_config_string(&cfg->user, var, val);
else if (!strcmp("imap.pass", var)) } else if (!strcmp("imap.pass", var)) {
FREE_AND_NULL(cfg->folder);
return git_config_string(&cfg->pass, var, val); return git_config_string(&cfg->pass, var, val);
else if (!strcmp("imap.tunnel", var)) } else if (!strcmp("imap.tunnel", var)) {
FREE_AND_NULL(cfg->folder);
return git_config_string(&cfg->tunnel, var, val); return git_config_string(&cfg->tunnel, var, val);
else if (!strcmp("imap.authmethod", var)) } else if (!strcmp("imap.authmethod", var)) {
FREE_AND_NULL(cfg->folder);
return git_config_string(&cfg->auth_method, var, val); return git_config_string(&cfg->auth_method, var, val);
else if (!strcmp("imap.port", var)) } else if (!strcmp("imap.port", var)) {
cfg->port = git_config_int(var, val, ctx->kvi); cfg->port = git_config_int(var, val, ctx->kvi);
else if (!strcmp("imap.host", var)) { } else if (!strcmp("imap.host", var)) {
if (!val) { if (!val) {
return config_error_nonbool(var); return config_error_nonbool(var);
} else { } else {
@ -1330,8 +1334,9 @@ static int git_imap_config(const char *var, const char *val,
val += 2; val += 2;
cfg->host = xstrdup(val); cfg->host = xstrdup(val);
} }
} else } else {
return git_default_config(var, val, ctx, cb); return git_default_config(var, val, ctx, cb);
}


return 0; return 0;
} }
@ -1503,6 +1508,7 @@ int cmd_main(int argc, const char **argv)
struct strbuf all_msgs = STRBUF_INIT; struct strbuf all_msgs = STRBUF_INIT;
int total; int total;
int nongit_ok; int nongit_ok;
int ret;


setup_git_directory_gently(&nongit_ok); setup_git_directory_gently(&nongit_ok);
git_config(git_imap_config, &server); git_config(git_imap_config, &server);
@ -1529,42 +1535,55 @@ int cmd_main(int argc, const char **argv)


if (!server.folder) { if (!server.folder) {
fprintf(stderr, "no imap store specified\n"); fprintf(stderr, "no imap store specified\n");
return 1; ret = 1;
goto out;
} }
if (!server.host) { if (!server.host) {
if (!server.tunnel) { if (!server.tunnel) {
fprintf(stderr, "no imap host specified\n"); fprintf(stderr, "no imap host specified\n");
return 1; ret = 1;
goto out;
} }
server.host = "tunnel"; server.host = xstrdup("tunnel");
} }


/* read the messages */ /* read the messages */
if (strbuf_read(&all_msgs, 0, 0) < 0) { if (strbuf_read(&all_msgs, 0, 0) < 0) {
error_errno(_("could not read from stdin")); error_errno(_("could not read from stdin"));
return 1; ret = 1;
goto out;
} }


if (all_msgs.len == 0) { if (all_msgs.len == 0) {
fprintf(stderr, "nothing to send\n"); fprintf(stderr, "nothing to send\n");
return 1; ret = 1;
goto out;
} }


total = count_messages(&all_msgs); total = count_messages(&all_msgs);
if (!total) { if (!total) {
fprintf(stderr, "no messages to send\n"); fprintf(stderr, "no messages to send\n");
return 1; ret = 1;
goto out;
} }


/* write it to the imap server */ /* write it to the imap server */


if (server.tunnel) if (server.tunnel)
return append_msgs_to_imap(&server, &all_msgs, total); ret = append_msgs_to_imap(&server, &all_msgs, total);

#ifdef USE_CURL_FOR_IMAP_SEND #ifdef USE_CURL_FOR_IMAP_SEND
if (use_curl) else if (use_curl)
return curl_append_msgs_to_imap(&server, &all_msgs, total); ret = curl_append_msgs_to_imap(&server, &all_msgs, total);
#endif #endif
else
ret = append_msgs_to_imap(&server, &all_msgs, total);


return append_msgs_to_imap(&server, &all_msgs, total); out:
free(server.tunnel);
free(server.host);
free(server.folder);
free(server.user);
free(server.pass);
free(server.auth_method);
return ret;
} }