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>
Brandon Casey committed
Aug 21, 2008 at 19:16 UTC
2cb1f36d5098060a4bac182da16ceed3197a57c2
2 files changed
+28
-2
remote.c
+27
-2
@@ -449,6 +449,26 @@ static int verify_refname(char *name, int is_glob)
449
return result;
450
}
451
452
+/*
453
+ * This function frees a refspec array.
454
+ * Warning: code paths should be checked to ensure that the src
455
+ * and dst pointers are always freeable pointers as well
456
+ * as the refspec pointer itself.
457
+ */
458
+void free_refspecs(struct refspec *refspec, int nr_refspec)
459
+{
460
+ int i;
461
+
462
+ if (!refspec)
463
+ return;
464
+
465
+ for (i = 0; i < nr_refspec; i++) {
466
+ free(refspec[i].src);
467
+ free(refspec[i].dst);
468
+ }
469
+ free(refspec);
470
+}
471
+
472
static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
473
{
474
int i;
@@ -567,7 +587,12 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp
587
588
invalid:
589
if (verify) {
570
- free(rs);
590
+ /*
591
+ * nr_refspec must be greater than zero and i must be valid
592
+ * since it is only possible to reach this point from within
593
+ * the for loop above.
594
+ */
595
+ free_refspecs(rs, i+1);
596
return NULL;
597
}
598
die("Invalid refspec '%s'", refspec[i]);
@@ -579,7 +604,7 @@ int valid_fetch_refspec(const char *fetch_refspec_str)
604
struct refspec *refspec;
605
606
refspec = parse_refspec_internal(1, fetch_refspec, 1, 1);
582
- free(refspec);
607
+ free_refspecs(refspec, 1);
608
return !!refspec;
609
}
610
remote.h
+1
@@ -78,6 +78,7 @@ void ref_remove_duplicates(struct ref *ref_map);
78
int valid_fetch_refspec(const char *refspec);
79
struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);
80
struct refspec *parse_push_refspec(int nr_refspec, const char **refspec);
81
+void free_refspecs(struct refspec *refspec, int nr_refspec);
82
83
int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
84
int nr_refspec, const char **refspec, int all);