summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a9da166)
raw | patch | inline | side by side (parent: a9da166)
author | Brandon Casey <casey@nrlssc.navy.mil> | |
Fri, 22 Aug 2008 00:16:30 +0000 (19:16 -0500) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Fri, 22 Aug 2008 07:15:37 +0000 (00:15 -0700) |
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>
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>
remote.c | patch | blob | history | |
remote.h | patch | blob | history |
diff --git a/remote.c b/remote.c
index 105668f8a3cf13c2a759e9da4d0acc50ef781de9..3ef09a44a14622bb175d2a18bc46c946cde9a8a1 100644 (file)
--- a/remote.c
+++ b/remote.c
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]);
struct refspec *refspec;
refspec = parse_refspec_internal(1, fetch_refspec, 1, 1);
- free(refspec);
+ free_refspecs(refspec, 1);
return !!refspec;
}
diff --git a/remote.h b/remote.h
index 091b1d041f8a4d255f59bfc001e098e692dbc15c..2601f6e76d52c6a201e3952fb8b2c988eed33700 100644 (file)
--- a/remote.h
+++ b/remote.h
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);