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>
This commit is contained in:
Junio C Hamano 2012-03-21 15:18:18 -07:00
parent a604ddef73
commit 2901bbe5be

View file

@ -207,6 +207,9 @@ static void free_patch(struct patch *patch)
free(fragment);
fragment = fragment_next;
}
free(patch->def_name);
free(patch->old_name);
free(patch->new_name);
free(patch);
}
@ -439,7 +442,7 @@ static char *squash_slash(char *name)
return name;
}
static char *find_name_gnu(const char *line, char *def, int p_value)
static char *find_name_gnu(const char *line, const char *def, int p_value)
{
struct strbuf name = STRBUF_INIT;
char *cp;
@ -462,11 +465,7 @@ static char *find_name_gnu(const char *line, char *def, int p_value)
cp++;
}
/* name can later be freed, so we need
* to memmove, not just return cp
*/
strbuf_remove(&name, 0, cp - name.buf);
free(def);
if (root)
strbuf_insert(&name, 0, root, root_len);
return squash_slash(strbuf_detach(&name, NULL));
@ -631,8 +630,13 @@ static size_t diff_timestamp_len(const char *line, size_t len)
return line + len - end;
}
static char *find_name_common(const char *line, char *def, int p_value,
const char *end, int terminate)
static char *null_strdup(const char *s)
{
return s ? xstrdup(s) : NULL;
}
static char *find_name_common(const char *line, const char *def,
int p_value, const char *end, int terminate)
{
int len;
const char *start = NULL;
@ -653,10 +657,10 @@ static char *find_name_common(const char *line, char *def, int p_value,
start = line;
}
if (!start)
return squash_slash(def);
return squash_slash(null_strdup(def));
len = line - start;
if (!len)
return squash_slash(def);
return squash_slash(null_strdup(def));
/*
* Generally we prefer the shorter name, especially
@ -667,8 +671,7 @@ static char *find_name_common(const char *line, char *def, int p_value,
if (def) {
int deflen = strlen(def);
if (deflen < len && !strncmp(start, def, deflen))
return squash_slash(def);
free(def);
return squash_slash(xstrdup(def));
}
if (root) {
@ -865,8 +868,10 @@ static void parse_traditional_patch(const char *first, const char *second, struc
name = find_name_traditional(first, NULL, p_value);
patch->old_name = name;
} else {
name = find_name_traditional(first, NULL, p_value);
name = find_name_traditional(second, name, p_value);
char *first_name;
first_name = find_name_traditional(first, NULL, p_value);
name = find_name_traditional(second, first_name, p_value);
free(first_name);
if (has_epoch_timestamp(first)) {
patch->is_new = 1;
patch->is_delete = 0;
@ -876,7 +881,8 @@ static void parse_traditional_patch(const char *first, const char *second, struc
patch->is_delete = 1;
patch->old_name = name;
} else {
patch->old_name = patch->new_name = name;
patch->old_name = name;
patch->new_name = xstrdup(name);
}
}
if (!name)
@ -926,13 +932,19 @@ static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name,
static int gitdiff_oldname(const char *line, struct patch *patch)
{
char *orig = patch->old_name;
patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, "old");
if (orig != patch->old_name)
free(orig);
return 0;
}
static int gitdiff_newname(const char *line, struct patch *patch)
{
char *orig = patch->new_name;
patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, "new");
if (orig != patch->new_name)
free(orig);
return 0;
}
@ -951,20 +963,23 @@ static int gitdiff_newmode(const char *line, struct patch *patch)
static int gitdiff_delete(const char *line, struct patch *patch)
{
patch->is_delete = 1;
patch->old_name = patch->def_name;
free(patch->old_name);
patch->old_name = null_strdup(patch->def_name);
return gitdiff_oldmode(line, patch);
}
static int gitdiff_newfile(const char *line, struct patch *patch)
{
patch->is_new = 1;
patch->new_name = patch->def_name;
free(patch->new_name);
patch->new_name = null_strdup(patch->def_name);
return gitdiff_newmode(line, patch);
}
static int gitdiff_copysrc(const char *line, struct patch *patch)
{
patch->is_copy = 1;
free(patch->old_name);
patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0;
}
@ -972,6 +987,7 @@ static int gitdiff_copysrc(const char *line, struct patch *patch)
static int gitdiff_copydst(const char *line, struct patch *patch)
{
patch->is_copy = 1;
free(patch->new_name);
patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0;
}
@ -979,6 +995,7 @@ static int gitdiff_copydst(const char *line, struct patch *patch)
static int gitdiff_renamesrc(const char *line, struct patch *patch)
{
patch->is_rename = 1;
free(patch->old_name);
patch->old_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0;
}
@ -986,6 +1003,7 @@ static int gitdiff_renamesrc(const char *line, struct patch *patch)
static int gitdiff_renamedst(const char *line, struct patch *patch)
{
patch->is_rename = 1;
free(patch->new_name);
patch->new_name = find_name(line, NULL, p_value ? p_value - 1 : 0, 0);
return 0;
}
@ -1426,7 +1444,8 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
if (!patch->def_name)
die("git diff header lacks filename information when removing "
"%d leading pathname components (line %d)" , p_value, linenr);
patch->old_name = patch->new_name = patch->def_name;
patch->old_name = xstrdup(patch->def_name);
patch->new_name = xstrdup(patch->def_name);
}
if (!patch->is_delete && !patch->new_name)
die("git diff header lacks filename information "
@ -3109,6 +3128,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
is_new:
patch->is_new = 1;
patch->is_delete = 0;
free(patch->old_name);
patch->old_name = NULL;
return 0;
}
@ -3689,15 +3709,8 @@ static void prefix_patches(struct patch *p)
if (!prefix || p->is_toplevel_relative)
return;
for ( ; p; p = p->next) {
if (p->new_name == p->old_name) {
char *prefixed = p->new_name;
prefix_one(&prefixed);
p->new_name = p->old_name = prefixed;
}
else {
prefix_one(&p->new_name);
prefix_one(&p->old_name);
}
prefix_one(&p->new_name);
prefix_one(&p->old_name);
}
}