fetch-pack: fix leaking sought refs
When calling `fetch_pack()` the caller is expected to pass in a set of sought-after refs that they want to fetch. This array gets massaged to not contain duplicate entries, which is done by replacing duplicate refs with `NULL` pointers. This modifies the caller-provided array, and in case we do unset any pointers the caller now loses track of that ref and cannot free it anymore. Now the obvious fix would be to not only unset these pointers, but to also free their contents. But this doesn't work because callers continue to use those refs. Another potential solution would be to copy the array in `fetch_pack()` so that we dont modify the caller-provided one. But that doesn't work either because the NULL-ness of those entries is used by callers to skip over ref entries that we didn't even try to fetch in `report_unmatched_refs()`. Instead, we make it the responsibility of our callers to duplicate these arrays as needed. It ain't pretty, but it works to plug the memory leak. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
61133e6ebb
commit
6f54d00439
@ -53,6 +53,7 @@ int cmd_fetch_pack(int argc,
|
||||
struct ref *fetched_refs = NULL, *remote_refs = NULL;
|
||||
const char *dest = NULL;
|
||||
struct ref **sought = NULL;
|
||||
struct ref **sought_to_free = NULL;
|
||||
int nr_sought = 0, alloc_sought = 0;
|
||||
int fd[2];
|
||||
struct string_list pack_lockfiles = STRING_LIST_INIT_DUP;
|
||||
@ -243,6 +244,13 @@ int cmd_fetch_pack(int argc,
|
||||
BUG("unknown protocol version");
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a shallow copy of `sought` so that we can free all of its entries.
|
||||
* This is because `fetch_pack()` will modify the array to evict some
|
||||
* entries, but won't free those.
|
||||
*/
|
||||
DUP_ARRAY(sought_to_free, sought, nr_sought);
|
||||
|
||||
fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought,
|
||||
&shallow, pack_lockfiles_ptr, version);
|
||||
|
||||
@ -280,7 +288,8 @@ int cmd_fetch_pack(int argc,
|
||||
oid_to_hex(&ref->old_oid), ref->name);
|
||||
|
||||
for (size_t i = 0; i < nr_sought; i++)
|
||||
free_one_ref(sought[i]);
|
||||
free_one_ref(sought_to_free[i]);
|
||||
free(sought_to_free);
|
||||
free(sought);
|
||||
free_refs(fetched_refs);
|
||||
free_refs(remote_refs);
|
||||
|
Reference in New Issue
Block a user