traverse_trees(): use stack array for name entries
We heap-allocate our arrays of name_entry structs, etc, with one entry
per tree we're asked to traverse. The code does a raw multiplication in
the xmalloc() call, which I find when auditing for integer overflows
during allocation.
We could "fix" this by using ALLOC_ARRAY() instead. But as it turns out,
the maximum size of these arrays is limited at compile time:
- merge_trees() always passes in 3 trees
- unpack_trees() and its brethren never pass in more than
MAX_UNPACK_TREES
So we can simplify even further by just using a stack array and bounding
it with MAX_UNPACK_TREES. There should be no concern with overflowing
the stack, since MAX_UNPACK_TREES is only 8 and the structs themselves
are small.
Note that since we're replacing xcalloc(), we have to move one of the
NULL initializations into a loop.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
667b76ec58
commit
8dd40c0472
13
tree-walk.c
13
tree-walk.c
@ -410,15 +410,20 @@ int traverse_trees(struct index_state *istate,
|
||||
struct traverse_info *info)
|
||||
{
|
||||
int error = 0;
|
||||
struct name_entry *entry = xmalloc(n*sizeof(*entry));
|
||||
struct name_entry entry[MAX_UNPACK_TREES];
|
||||
int i;
|
||||
struct tree_desc_x *tx = xcalloc(n, sizeof(*tx));
|
||||
struct tree_desc_x tx[ARRAY_SIZE(entry)];
|
||||
struct strbuf base = STRBUF_INIT;
|
||||
int interesting = 1;
|
||||
char *traverse_path;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (n >= ARRAY_SIZE(entry))
|
||||
BUG("traverse_trees() called with too many trees (%d)", n);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
tx[i].d = t[i];
|
||||
tx[i].skip = NULL;
|
||||
}
|
||||
|
||||
if (info->prev) {
|
||||
strbuf_make_traverse_path(&base, info->prev,
|
||||
@ -506,10 +511,8 @@ int traverse_trees(struct index_state *istate,
|
||||
if (mask & (1ul << i))
|
||||
update_extended_entry(tx + i, entry + i);
|
||||
}
|
||||
free(entry);
|
||||
for (i = 0; i < n; i++)
|
||||
free_extended_entry(tx + i);
|
||||
free(tx);
|
||||
free(traverse_path);
|
||||
info->traverse_path = NULL;
|
||||
strbuf_release(&base);
|
||||
|
||||
Reference in New Issue
Block a user