@matheusbsbs / matheus-bagliano / commits / 2cb1f36d50
Fork 0

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);