зеркало из https://github.com/microsoft/git.git
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:
Родитель
a9da1663df
Коммит
2cb1f36d50
29
remote.c
29
remote.c
|
@ -449,6 +449,26 @@ static int verify_refname(char *name, int is_glob)
|
||||||
return result;
|
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)
|
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -567,7 +587,12 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
|
||||||
|
|
||||||
invalid:
|
invalid:
|
||||||
if (verify) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
die("Invalid refspec '%s'", refspec[i]);
|
die("Invalid refspec '%s'", refspec[i]);
|
||||||
|
@ -579,7 +604,7 @@ int valid_fetch_refspec(const char *fetch_refspec_str)
|
||||||
struct refspec *refspec;
|
struct refspec *refspec;
|
||||||
|
|
||||||
refspec = parse_refspec_internal(1, fetch_refspec, 1, 1);
|
refspec = parse_refspec_internal(1, fetch_refspec, 1, 1);
|
||||||
free(refspec);
|
free_refspecs(refspec, 1);
|
||||||
return !!refspec;
|
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);
|
int valid_fetch_refspec(const char *refspec);
|
||||||
struct refspec *parse_fetch_refspec(int nr_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);
|
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 match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
|
||||||
int nr_refspec, const char **refspec, int all);
|
int nr_refspec, const char **refspec, int all);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче