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>

Patrick Steinhardt committed Jun 7, 2024 at 08:39 UTC 6d1f198f346fb218e06e730bac28609aa402a648
1 file changed +42 -23
imap-send.c
+42 -23
@@ -69,7 +69,6 @@ static void imap_warn(const char *, ...);
69 static char *next_arg(char **);
70
71 struct imap_server_conf {
72 - const char *name;
72 char *tunnel;
73 char *host;
74 int port;
@@ -1300,23 +1299,28 @@ static int git_imap_config(const char *var, const char *val,
1299 {
1300 struct imap_server_conf *cfg = cb;
1301
1303 - if (!strcmp("imap.sslverify", var))
1302 + if (!strcmp("imap.sslverify", var)) {
1303 cfg->ssl_verify = git_config_bool(var, val);
1305 - else if (!strcmp("imap.preformattedhtml", var))
1304 + } else if (!strcmp("imap.preformattedhtml", var)) {
1305 cfg->use_html = git_config_bool(var, val);
1307 - else if (!strcmp("imap.folder", var))
1306 + } else if (!strcmp("imap.folder", var)) {
1307 + FREE_AND_NULL(cfg->folder);
1308 return git_config_string(&cfg->folder, var, val);
1309 - else if (!strcmp("imap.user", var))
1309 + } else if (!strcmp("imap.user", var)) {
1310 + FREE_AND_NULL(cfg->folder);
1311 return git_config_string(&cfg->user, var, val);
1311 - else if (!strcmp("imap.pass", var))
1312 + } else if (!strcmp("imap.pass", var)) {
1313 + FREE_AND_NULL(cfg->folder);
1314 return git_config_string(&cfg->pass, var, val);
1313 - else if (!strcmp("imap.tunnel", var))
1315 + } else if (!strcmp("imap.tunnel", var)) {
1316 + FREE_AND_NULL(cfg->folder);
1317 return git_config_string(&cfg->tunnel, var, val);
1315 - else if (!strcmp("imap.authmethod", var))
1318 + } else if (!strcmp("imap.authmethod", var)) {
1319 + FREE_AND_NULL(cfg->folder);
1320 return git_config_string(&cfg->auth_method, var, val);
1317 - else if (!strcmp("imap.port", var))
1321 + } else if (!strcmp("imap.port", var)) {
1322 cfg->port = git_config_int(var, val, ctx->kvi);
1319 - else if (!strcmp("imap.host", var)) {
1323 + } else if (!strcmp("imap.host", var)) {
1324 if (!val) {
1325 return config_error_nonbool(var);
1326 } else {
@@ -1330,8 +1334,9 @@ static int git_imap_config(const char *var, const char *val,
1334 val += 2;
1335 cfg->host = xstrdup(val);
1336 }
1333 - } else
1337 + } else {
1338 return git_default_config(var, val, ctx, cb);
1339 + }
1340
1341 return 0;
1342 }
@@ -1503,6 +1508,7 @@ int cmd_main(int argc, const char **argv)
1508 struct strbuf all_msgs = STRBUF_INIT;
1509 int total;
1510 int nongit_ok;
1511 + int ret;
1512
1513 setup_git_directory_gently(&nongit_ok);
1514 git_config(git_imap_config, &server);
@@ -1529,42 +1535,55 @@ int cmd_main(int argc, const char **argv)
1535
1536 if (!server.folder) {
1537 fprintf(stderr, "no imap store specified\n");
1532 - return 1;
1538 + ret = 1;
1539 + goto out;
1540 }
1541 if (!server.host) {
1542 if (!server.tunnel) {
1543 fprintf(stderr, "no imap host specified\n");
1537 - return 1;
1544 + ret = 1;
1545 + goto out;
1546 }
1539 - server.host = "tunnel";
1547 + server.host = xstrdup("tunnel");
1548 }
1549
1550 /* read the messages */
1551 if (strbuf_read(&all_msgs, 0, 0) < 0) {
1552 error_errno(_("could not read from stdin"));
1545 - return 1;
1553 + ret = 1;
1554 + goto out;
1555 }
1556
1557 if (all_msgs.len == 0) {
1558 fprintf(stderr, "nothing to send\n");
1550 - return 1;
1559 + ret = 1;
1560 + goto out;
1561 }
1562
1563 total = count_messages(&all_msgs);
1564 if (!total) {
1565 fprintf(stderr, "no messages to send\n");
1556 - return 1;
1566 + ret = 1;
1567 + goto out;
1568 }
1569
1570 /* write it to the imap server */
1571
1572 if (server.tunnel)
1562 - return append_msgs_to_imap(&server, &all_msgs, total);
1563 -
1573 + ret = append_msgs_to_imap(&server, &all_msgs, total);
1574 #ifdef USE_CURL_FOR_IMAP_SEND
1565 - if (use_curl)
1566 - return curl_append_msgs_to_imap(&server, &all_msgs, total);
1575 + else if (use_curl)
1576 + ret = curl_append_msgs_to_imap(&server, &all_msgs, total);
1577 #endif
1568 -
1569 - return append_msgs_to_imap(&server, &all_msgs, total);
1578 + else
1579 + ret = append_msgs_to_imap(&server, &all_msgs, total);
1580 +
1581 +out:
1582 + free(server.tunnel);
1583 + free(server.host);
1584 + free(server.folder);
1585 + free(server.user);
1586 + free(server.pass);
1587 + free(server.auth_method);
1588 + return ret;
1589 }