Skip to content

Commit c6d26a9

Browse files
peffgitster
authored andcommitted
format-patch: free elements of rev.ref_message_ids list
When we are showing multiple patches with format-patch, we have to repeatedly overwrite the rev.message_id field. We take care to avoid leaking the old value by either freeing it, or adding it to ref_message_ids, a string list of ids to reference in subsequent messages. But unfortunately we do leak the value via that string list. We try to clear the string list, courtesy of 89f45cf (format-patch: don't leak "extra_headers" or "ref_message_ids", 2022-04-13). But since it was initialized as "nodup", the string list doesn't realize it owns the strings, and it leaks them. We have two options here: 1. Continue to init with "nodup", but then tweak the value of ref_message_ids.strdup_strings just before clearing. 2. Init with "dup", but use "append_nodup" when transferring ownership of strings to the list. Clearing just works. I picked the second here, as I think it calls attention to the tricky part (transferring ownership via the nodup call). There's one other related fix we have to do, though. We also insert the result of clean_message_id() into the list. This _sometimes_ allocates and sometimes does not, depending on whether we have to remove cruft from the end of the string. Let's teach it to consistently return an allocated string, so that the caller knows it must be freed. There's no new test here, as the leak can already be seen in t4014.44 (as well as others in that script). We can't mark all of t4014 as leak-free, though, as there are other unrelated leaks that it triggers. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cfa1209 commit c6d26a9

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

builtin/log.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
14011401
}
14021402
}
14031403

1404-
static const char *clean_message_id(const char *msg_id)
1404+
static char *clean_message_id(const char *msg_id)
14051405
{
14061406
char ch;
14071407
const char *a, *z, *m;
@@ -1419,7 +1419,7 @@ static const char *clean_message_id(const char *msg_id)
14191419
if (!z)
14201420
die(_("insane in-reply-to: %s"), msg_id);
14211421
if (++z == m)
1422-
return a;
1422+
return xstrdup(a);
14231423
return xmemdupz(a, z - a);
14241424
}
14251425

@@ -2305,11 +2305,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
23052305

23062306
if (in_reply_to || thread || cover_letter) {
23072307
rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids));
2308-
string_list_init_nodup(rev.ref_message_ids);
2308+
string_list_init_dup(rev.ref_message_ids);
23092309
}
23102310
if (in_reply_to) {
2311-
const char *msgid = clean_message_id(in_reply_to);
2312-
string_list_append(rev.ref_message_ids, msgid);
2311+
char *msgid = clean_message_id(in_reply_to);
2312+
string_list_append_nodup(rev.ref_message_ids, msgid);
23132313
}
23142314
rev.numbered_files = just_numbers;
23152315
rev.patch_suffix = fmt_patch_suffix;
@@ -2365,8 +2365,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
23652365
&& (!cover_letter || rev.nr > 1))
23662366
free(rev.message_id);
23672367
else
2368-
string_list_append(rev.ref_message_ids,
2369-
rev.message_id);
2368+
string_list_append_nodup(rev.ref_message_ids,
2369+
rev.message_id);
23702370
}
23712371
gen_message_id(&rev, oid_to_hex(&commit->object.oid));
23722372
}

0 commit comments

Comments
 (0)