apply: free patch->{def,old,new}_name fields

These were all allocated in the heap by parsing the header parts of the patch, but we did not bother to free them. Some used to share the memory (e.g. copying def_name to old_name) so this is not just the matter of adding three calls to free(). Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Mar 21, 2012 at 15:18 UTC 2901bbe5be41af3161fe99dede505833f26ff2bf
1 file changed +39 -26
builtin/apply.c
+39 -26
@@ -207,6 +207,9 @@ static void free_patch(struct patch *patch)
207 free(fragment);
208 fragment = fragment_next;
209 }
210 + free(patch->def_name);
211 + free(patch->old_name);
212 + free(patch->new_name);
213 free(patch);
214 }
215
@@ -439,7 +442,7 @@ static char *squash_slash(char *name)
442 return name;
443 }
444
442 -static char *find_name_gnu(const char *line, char *def, int p_value)
445 +static char *find_name_gnu(const char *line, const char *def, int p_value)
446 {
447 struct strbuf name = STRBUF_INIT;
448 char *cp;
@@ -462,11 +465,7 @@ static char *find_name_gnu(const char *line, char *def, int p_value)
465 cp++;
466 }
467
465 - /* name can later be freed, so we need
466 - * to memmove, not just return cp
467 - */
468 strbuf_remove(&name, 0, cp - name.buf);
469 - free(def);
469 if (root)
470 strbuf_insert(&name, 0, root, root_len);
471 return squash_slash(strbuf_detach(&name, NULL));
@@ -631,8 +630,13 @@ static size_t diff_timestamp_len(const char *line, size_t len)
630 return line + len - end;
631 }
632
634 -static char *find_name_common(const char *line, char *def, int p_value,
635 - const char *end, int terminate)
633 +static char *null_strdup(const char *s)
634 +{
635 + return s ? xstrdup(s) : NULL;
636 +}
637 +
638 +static char *find_name_common(const char *line, const char *def,
639 + int p_value, const char *end, int terminate)
640 {
641 int len;
642 const char *start = NULL;
@@ -653,10 +657,10 @@ static char *find_name_common(const char *line, char *def, int p_value,
657 start = line;
658 }
659 if (!start)
656 - return squash_slash(def);
660 + return squash_slash(null_strdup(def));
661 len = line - start;
662 if (!len)
659 - return squash_slash(def);
663 + return squash_slash(null_strdup(def));
664
665 /*
666 * Generally we prefer the shorter name, especially
@@ -667,8 +671,7 @@ static char *find_name_common(const char *line, char *def, int p_value,
671 if (def) {
672 int deflen = strlen(def);
673 if (deflen < len && !strncmp(start, def, deflen))
670 - return squash_slash(def);
671 - free(def);
674 + return squash_slash(xstrdup(def));
675 }
676
677 if (root) {
@@ -865,8 +868,10 @@ static void parse_traditional_patch(const char *first, const char *second, struc
868 name = find_name_traditional(first, NULL, p_value);
869 patch->old_name = name;
870 } else {
868 - name = find_name_traditional(first, NULL, p_value);
869 - name = find_name_traditional(second, name, p_value);
871 + char *first_name;
872 + first_name = find_name_traditional(first, NULL, p_value);
873 + name = find_name_traditional(second, first_name, p_value);
874 + free(first_name);
875 if (has_epoch_timestamp(first)) {
876 patch->is_new = 1;
877 patch->is_delete = 0;
@@ -876,7 +881,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc
881 patch->is_delete = 1;
882 patch->old_name = name;
883 } else {
879 - patch->old_name = patch->new_name = name;
884 + patch->old_name = name;
885 + patch->new_name = xstrdup(name);
886 }
887 }
888 if (!name)
@@ -926,13 +932,19 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
932
933 static int gitdiff_oldname(const char *line, struct patch *patch)
934 {
935 + char *orig = patch->old_name;
936 patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, "old");
937 + if (orig != patch->old_name)
938 + free(orig);
939 return 0;
940 }
941
942 static int gitdiff_newname(const char *line, struct patch *patch)
943 {
944 + char *orig = patch->new_name;
945 patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, "new");
946 + if (orig != patch->new_name)
947 + free(orig);
948 return 0;
949 }
950
@@ -951,20 +963,23 @@ static int gitdiff_newmode(const char *line, struct patch *patch)
963 static int gitdiff_delete(const char *line, struct patch *patch)
964 {
965 patch->is_delete = 1;
954 - patch->old_name = patch->def_name;
966 + free(patch->old_name);
967 + patch->old_name = null_strdup(patch->def_name);
968 return gitdiff_oldmode(line, patch);
969 }
970
971 static int gitdiff_newfile(const char *line, struct patch *patch)
972 {
973 patch->is_new = 1;
961 - patch->new_name = patch->def_name;
974 + free(patch->new_name);
975 + patch->new_name = null_strdup(patch->def_name);
976 return gitdiff_newmode(line, patch);
977 }
978
979 static int gitdiff_copysrc(const char *line, struct patch *patch)
980 {
981 patch->is_copy = 1;
982 + free(patch->old_name);
983 patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
984 return 0;
985 }
@@ -972,6 +987,7 @@ static int gitdiff_copysrc(const char *line, struct patch *patch)
987 static int gitdiff_copydst(const char *line, struct patch *patch)
988 {
989 patch->is_copy = 1;
990 + free(patch->new_name);
991 patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
992 return 0;
993 }
@@ -979,6 +995,7 @@ static int gitdiff_copydst(const char *line, struct patch *patch)
995 static int gitdiff_renamesrc(const char *line, struct patch *patch)
996 {
997 patch->is_rename = 1;
998 + free(patch->old_name);
999 patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
1000 return 0;
1001 }
@@ -986,6 +1003,7 @@ static int gitdiff_renamesrc(const char *line, struct patch *patch)
1003 static int gitdiff_renamedst(const char *line, struct patch *patch)
1004 {
1005 patch->is_rename = 1;
1006 + free(patch->new_name);
1007 patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
1008 return 0;
1009 }
@@ -1426,7 +1444,8 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
1444 if (!patch->def_name)
1445 die("git diff header lacks filename information when removing "
1446 "%d leading pathname components (line %d)" , p_value, linenr);
1429 - patch->old_name = patch->new_name = patch->def_name;
1447 + patch->old_name = xstrdup(patch->def_name);
1448 + patch->new_name = xstrdup(patch->def_name);
1449 }
1450 if (!patch->is_delete && !patch->new_name)
1451 die("git diff header lacks filename information "
@@ -3109,6 +3128,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
3128 is_new:
3129 patch->is_new = 1;
3130 patch->is_delete = 0;
3131 + free(patch->old_name);
3132 patch->old_name = NULL;
3133 return 0;
3134 }
@@ -3689,15 +3709,8 @@ static void prefix_patches(struct patch *p)
3709 if (!prefix || p->is_toplevel_relative)
3710 return;
3711 for ( ; p; p = p->next) {
3692 - if (p->new_name == p->old_name) {
3693 - char *prefixed = p->new_name;
3694 - prefix_one(&prefixed);
3695 - p->new_name = p->old_name = prefixed;
3696 - }
3697 - else {
3698 - prefix_one(&p->new_name);
3699 - prefix_one(&p->old_name);
3700 - }
3712 + prefix_one(&p->new_name);
3713 + prefix_one(&p->old_name);
3714 }
3715 }
3716