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