builtin/fetch-pack: fix leaking refs

We build several ref lists in git-fetch-pack(1), but never free them. Fix those leaks. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Aug 22, 2024 at 11:17 UTC 46e440694f09e4cb23c8bba6cd49cc035df6ce99
1 file changed +12 -8
builtin/fetch-pack.c
+12 -8
@@ -46,7 +46,7 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
46 int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED)
47 {
48 int i, ret;
49 - struct ref *ref = NULL;
49 + struct ref *fetched_refs = NULL, *remote_refs = NULL;
50 const char *dest = NULL;
51 struct ref **sought = NULL;
52 int nr_sought = 0, alloc_sought = 0;
@@ -228,19 +228,20 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED)
228 version = discover_version(&reader);
229 switch (version) {
230 case protocol_v2:
231 - get_remote_refs(fd[1], &reader, &ref, 0, NULL, NULL,
231 + get_remote_refs(fd[1], &reader, &remote_refs, 0, NULL, NULL,
232 args.stateless_rpc);
233 break;
234 case protocol_v1:
235 case protocol_v0:
236 - get_remote_heads(&reader, &ref, 0, NULL, &shallow);
236 + get_remote_heads(&reader, &remote_refs, 0, NULL, &shallow);
237 break;
238 case protocol_unknown_version:
239 BUG("unknown protocol version");
240 }
241
242 - ref = fetch_pack(&args, fd, ref, sought, nr_sought,
242 + fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought,
243 &shallow, pack_lockfiles_ptr, version);
244 +
245 if (pack_lockfiles.nr) {
246 int i;
247
@@ -260,7 +261,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED)
261 if (finish_connect(conn))
262 return 1;
263
263 - ret = !ref;
264 + ret = !fetched_refs;
265
266 /*
267 * If the heads to pull were given, we should have consumed
@@ -270,11 +271,14 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED)
271 */
272 ret |= report_unmatched_refs(sought, nr_sought);
273
273 - while (ref) {
274 + for (struct ref *ref = fetched_refs; ref; ref = ref->next)
275 printf("%s %s\n",
276 oid_to_hex(&ref->old_oid), ref->name);
276 - ref = ref->next;
277 - }
277
278 + for (size_t i = 0; i < nr_sought; i++)
279 + free_one_ref(sought[i]);
280 + free(sought);
281 + free_refs(fetched_refs);
282 + free_refs(remote_refs);
283 return ret;
284 }