Skip to content

Commit 8dd40c0

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 667b76e commit 8dd40c0

File tree

1 file changed

+8
-5
lines changed

1 file changed

+8
-5
lines changed

tree-walk.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,15 +410,20 @@ int traverse_trees(struct index_state *istate,
410410
struct traverse_info *info)
411411
{
412412
int error = 0;
413-
struct name_entry *entry = xmalloc(n*sizeof(*entry));
413+
struct name_entry entry[MAX_UNPACK_TREES];
414414
int i;
415-
struct tree_desc_x *tx = xcalloc(n, sizeof(*tx));
415+
struct tree_desc_x tx[ARRAY_SIZE(entry)];
416416
struct strbuf base = STRBUF_INIT;
417417
int interesting = 1;
418418
char *traverse_path;
419419

420-
for (i = 0; i < n; i++)
420+
if (n >= ARRAY_SIZE(entry))
421+
BUG("traverse_trees() called with too many trees (%d)", n);
422+
423+
for (i = 0; i < n; i++) {
421424
tx[i].d = t[i];
425+
tx[i].skip = NULL;
426+
}
422427

423428
if (info->prev) {
424429
strbuf_make_traverse_path(&base, info->prev,
@@ -506,10 +511,8 @@ int traverse_trees(struct index_state *istate,
506511
if (mask & (1ul << i))
507512
update_extended_entry(tx + i, entry + i);
508513
}
509-
free(entry);
510514
for (i = 0; i < n; i++)
511515
free_extended_entry(tx + i);
512-
free(tx);
513516
free(traverse_path);
514517
info->traverse_path = NULL;
515518
strbuf_release(&base);

0 commit comments

Comments
 (0)