1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 04:49:43 +01:00

fetch: free "raw" string when shrinking refspec

The "--prefetch" option to git-fetch modifies the default refspec,
including eliminating some entries entirely. When we drop an entry we
free the strings in the refspec_item, but we forgot to free the matching
string in the "raw" array of the refspec struct. There's no behavioral
bug here (since we correctly shrink the raw array, too), but we're
leaking the allocated string.

Let's add in the leak-fix, and while we're at it drop "const" from
the type of the raw string array. These strings are always allocated by
refspec_append(), etc, and this makes the memory ownership more clear.

This is all a bit more intimate with the refspec code than I'd like, and
I suspect it would be better if each refspec_item held on to its own raw
string, we had a single array, and we could use refspec_item_clear() to
clean up everything. But that's a non-trivial refactoring, since
refspec_item structs can be held outside of a "struct refspec", without
having a matching raw string at all. So let's leave that for now and
just fix the leak in the most immediate way.

This lets us mark t5582 as leak-free.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2024-09-24 17:57:40 -04:00 committed by Junio C Hamano
parent e00e1cff0d
commit ea4780307c
4 changed files with 4 additions and 2 deletions

View file

@ -456,6 +456,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
free(rs->items[i].src); free(rs->items[i].src);
free(rs->items[i].dst); free(rs->items[i].dst);
free(rs->raw[i]);
for (j = i + 1; j < rs->nr; j++) { for (j = i + 1; j < rs->nr; j++) {
rs->items[j - 1] = rs->items[j]; rs->items[j - 1] = rs->items[j];

View file

@ -225,7 +225,7 @@ void refspec_clear(struct refspec *rs)
rs->nr = 0; rs->nr = 0;
for (i = 0; i < rs->raw_nr; i++) for (i = 0; i < rs->raw_nr; i++)
free((char *)rs->raw[i]); free(rs->raw[i]);
FREE_AND_NULL(rs->raw); FREE_AND_NULL(rs->raw);
rs->raw_alloc = 0; rs->raw_alloc = 0;
rs->raw_nr = 0; rs->raw_nr = 0;

View file

@ -43,7 +43,7 @@ struct refspec {
int alloc; int alloc;
int nr; int nr;
const char **raw; char **raw;
int raw_alloc; int raw_alloc;
int raw_nr; int raw_nr;

View file

@ -8,6 +8,7 @@ test_description='"git fetch" with negative refspecs.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '