remote.c: add a function for deleting a refspec array and use it (twice)
A number of call sites allocate memory for a refspec array, populate its members with heap memory, and then free only the refspec pointer while leaking the memory allocated for the member elements. Provide a function for freeing the elements of a refspec array and the array itself. Caution to callers: code paths must be checked to ensure that the refspec members "src" and "dst" can be passed to free. Signed-off-by: Brandon Casey <casey@nrlssc.navy.mil> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
a9da1663df
commit
2cb1f36d50
29
remote.c
29
remote.c
@ -449,6 +449,26 @@ static int verify_refname(char *name, int is_glob)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function frees a refspec array.
|
||||
* Warning: code paths should be checked to ensure that the src
|
||||
* and dst pointers are always freeable pointers as well
|
||||
* as the refspec pointer itself.
|
||||
*/
|
||||
void free_refspecs(struct refspec *refspec, int nr_refspec)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!refspec)
|
||||
return;
|
||||
|
||||
for (i = 0; i < nr_refspec; i++) {
|
||||
free(refspec[i].src);
|
||||
free(refspec[i].dst);
|
||||
}
|
||||
free(refspec);
|
||||
}
|
||||
|
||||
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
|
||||
{
|
||||
int i;
|
||||
@ -567,7 +587,12 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
|
||||
|
||||
invalid:
|
||||
if (verify) {
|
||||
free(rs);
|
||||
/*
|
||||
* nr_refspec must be greater than zero and i must be valid
|
||||
* since it is only possible to reach this point from within
|
||||
* the for loop above.
|
||||
*/
|
||||
free_refspecs(rs, i+1);
|
||||
return NULL;
|
||||
}
|
||||
die("Invalid refspec '%s'", refspec[i]);
|
||||
@ -579,7 +604,7 @@ int valid_fetch_refspec(const char *fetch_refspec_str)
|
||||
struct refspec *refspec;
|
||||
|
||||
refspec = parse_refspec_internal(1, fetch_refspec, 1, 1);
|
||||
free(refspec);
|
||||
free_refspecs(refspec, 1);
|
||||
return !!refspec;
|
||||
}
|
||||
|
||||
|
1
remote.h
1
remote.h
@ -78,6 +78,7 @@ void ref_remove_duplicates(struct ref *ref_map);
|
||||
int valid_fetch_refspec(const char *refspec);
|
||||
struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);
|
||||
struct refspec *parse_push_refspec(int nr_refspec, const char **refspec);
|
||||
void free_refspecs(struct refspec *refspec, int nr_refspec);
|
||||
|
||||
int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
|
||||
int nr_refspec, const char **refspec, int all);
|
||||
|
Loading…
Reference in New Issue
Block a user