diff options
author | Jeff King <peff@peff.net> | 2020-01-30 04:53:38 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-01-30 13:55:30 -0800 |
commit | 8dd40c0472a8f51f4fba4b8fd28dc3e9421cd7d7 (patch) | |
tree | a1b1355b6075426f066cfca9c4ad0a4843c9398a /tree-walk.c | |
parent | walker_fetch(): avoid raw array length computation (diff) | |
download | tgif-8dd40c0472a8f51f4fba4b8fd28dc3e9421cd7d7.tar.xz |
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>
Diffstat (limited to 'tree-walk.c')
-rw-r--r-- | tree-walk.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/tree-walk.c b/tree-walk.c index d5a8e096a6..3093cf7098 100644 --- a/tree-walk.c +++ b/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); |