@ -207,6 +207,9 @@ static void free_patch(struct patch *patch)
@@ -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)
@@ -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)
@@ -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)
@@ -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,
@@ -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,
@@ -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
@@ -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
@@ -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,
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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
@@ -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
@@ -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)
@@ -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);
}
}