Browse Source

pathspec: copy and free owned memory

The 'original' string entry in a pathspec_item is only duplicated some
of the time, instead always make a copy of the original and take
ownership of the memory.

Since both 'match' and 'original' string entries in a pathspec_item are
owned by the pathspec struct, they need to be freed when clearing the
pathspec struct (in 'clear_pathspec()') and duplicated when copying the
pathspec struct (in 'copy_pathspec()').

Also change the type of 'match' and 'original' to 'char *' in order to
more explicitly show the ownership of the memory.

Signed-off-by: Brandon Williams <bmwill@google.com>
Reviewed-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Brandon Williams 8 years ago committed by Junio C Hamano
parent
commit
8aee769fa1
  1. 23
      pathspec.c
  2. 4
      pathspec.h

23
pathspec.c

@ -259,8 +259,9 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
} }
strbuf_addstr(&sb, match); strbuf_addstr(&sb, match);
item->original = strbuf_detach(&sb, NULL); item->original = strbuf_detach(&sb, NULL);
} else } else {
item->original = elt; item->original = xstrdup(elt);
}
item->len = strlen(item->match); item->len = strlen(item->match);
item->prefix = prefixlen; item->prefix = prefixlen;


@ -388,8 +389,8 @@ void parse_pathspec(struct pathspec *pathspec,
die("BUG: PATHSPEC_PREFER_CWD requires arguments"); die("BUG: PATHSPEC_PREFER_CWD requires arguments");


pathspec->items = item = xcalloc(1, sizeof(*item)); pathspec->items = item = xcalloc(1, sizeof(*item));
item->match = prefix; item->match = xstrdup(prefix);
item->original = prefix; item->original = xstrdup(prefix);
item->nowildcard_len = item->len = strlen(prefix); item->nowildcard_len = item->len = strlen(prefix);
item->prefix = item->len; item->prefix = item->len;
pathspec->nr = 1; pathspec->nr = 1;
@ -453,13 +454,27 @@ void parse_pathspec(struct pathspec *pathspec,


void copy_pathspec(struct pathspec *dst, const struct pathspec *src) void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
{ {
int i;

*dst = *src; *dst = *src;
ALLOC_ARRAY(dst->items, dst->nr); ALLOC_ARRAY(dst->items, dst->nr);
COPY_ARRAY(dst->items, src->items, dst->nr); COPY_ARRAY(dst->items, src->items, dst->nr);

for (i = 0; i < dst->nr; i++) {
dst->items[i].match = xstrdup(src->items[i].match);
dst->items[i].original = xstrdup(src->items[i].original);
}
} }


void clear_pathspec(struct pathspec *pathspec) void clear_pathspec(struct pathspec *pathspec)
{ {
int i;

for (i = 0; i < pathspec->nr; i++) {
free(pathspec->items[i].match);
free(pathspec->items[i].original);
}
free(pathspec->items); free(pathspec->items);
pathspec->items = NULL; pathspec->items = NULL;
pathspec->nr = 0;
} }

4
pathspec.h

@ -25,8 +25,8 @@ struct pathspec {
unsigned magic; unsigned magic;
int max_depth; int max_depth;
struct pathspec_item { struct pathspec_item {
const char *match; char *match;
const char *original; char *original;
unsigned magic; unsigned magic;
int len, prefix; int len, prefix;
int nowildcard_len; int nowildcard_len;

Loading…
Cancel
Save