Skip to content

Commit 3780608

Browse files
peffgitster
authored andcommitted
tree-walk: use size_t consistently
We store and manipulate the cumulative traverse_info.pathlen as an "int", which can overflow when we are fed ridiculously long pathnames (e.g., ones at the edge of 2GB or 4GB, even if the individual tree entry names are smaller than that). The results can be confusing, though after some prodding I was not able to use this integer overflow to cause an under-allocated buffer. Let's consistently use size_t to generate and store these, and make sure our addition doesn't overflow. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9055384 commit 3780608

File tree

3 files changed

+8
-8
lines changed

3 files changed

+8
-8
lines changed

tree-walk.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ int tree_entry_gently(struct tree_desc *desc, struct name_entry *entry)
168168

169169
void setup_traverse_info(struct traverse_info *info, const char *base)
170170
{
171-
int pathlen = strlen(base);
171+
size_t pathlen = strlen(base);
172172
static struct traverse_info dummy;
173173

174174
memset(info, 0, sizeof(*info));
@@ -184,7 +184,7 @@ void setup_traverse_info(struct traverse_info *info, const char *base)
184184
char *make_traverse_path(char *path, const struct traverse_info *info,
185185
const char *name, size_t namelen)
186186
{
187-
int pathlen = info->pathlen;
187+
size_t pathlen = info->pathlen;
188188

189189
path[pathlen + namelen] = 0;
190190
for (;;) {

tree-walk.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct traverse_info {
6060
size_t namelen;
6161
unsigned mode;
6262

63-
int pathlen;
63+
size_t pathlen;
6464
struct pathspec *pathspec;
6565

6666
unsigned long df_conflicts;
@@ -74,9 +74,9 @@ char *make_traverse_path(char *path, const struct traverse_info *info,
7474
const char *name, size_t namelen);
7575
void setup_traverse_info(struct traverse_info *info, const char *base);
7676

77-
static inline int traverse_path_len(const struct traverse_info *info, const struct name_entry *n)
77+
static inline size_t traverse_path_len(const struct traverse_info *info, const struct name_entry *n)
7878
{
79-
return info->pathlen + tree_entry_len(n);
79+
return st_add(info->pathlen, tree_entry_len(n));
8080
}
8181

8282
/* in general, positive means "kind of interesting" */

unpack-trees.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ static int index_pos_by_traverse_info(struct name_entry *names,
686686
struct traverse_info *info)
687687
{
688688
struct unpack_trees_options *o = info->data;
689-
int len = traverse_path_len(info, names);
689+
size_t len = traverse_path_len(info, names);
690690
char *name = xmalloc(len + 1 /* slash */ + 1 /* NUL */);
691691
int pos;
692692

@@ -814,7 +814,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask,
814814
newinfo.name = p->path;
815815
newinfo.namelen = p->pathlen;
816816
newinfo.mode = p->mode;
817-
newinfo.pathlen += tree_entry_len(p) + 1;
817+
newinfo.pathlen = st_add3(newinfo.pathlen, tree_entry_len(p), 1);
818818
newinfo.df_conflicts |= df_conflicts;
819819

820820
/*
@@ -960,7 +960,7 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info,
960960
struct index_state *istate,
961961
int is_transient)
962962
{
963-
int len = traverse_path_len(info, n);
963+
size_t len = traverse_path_len(info, n);
964964
struct cache_entry *ce =
965965
is_transient ?
966966
make_empty_transient_cache_entry(len) :

0 commit comments

Comments
 (0)