@matheusbsbs / matheus-bagliano / commits / 8dd40c0472
Fork 0

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>

Jeff King committed Jan 30, 2020 at 04:53 UTC 8dd40c0472a8f51f4fba4b8fd28dc3e9421cd7d7
1 file changed +8 -5
tree-walk.c
+8 -5
@@ -410,15 +410,20 @@ int traverse_trees(struct index_state *istate,
410 struct traverse_info *info)
411 {
412 int error = 0;
413 - struct name_entry *entry = xmalloc(n*sizeof(*entry));
413 + struct name_entry entry[MAX_UNPACK_TREES];
414 int i;
415 - struct tree_desc_x *tx = xcalloc(n, sizeof(*tx));
415 + struct tree_desc_x tx[ARRAY_SIZE(entry)];
416 struct strbuf base = STRBUF_INIT;
417 int interesting = 1;
418 char *traverse_path;
419
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++) {
424 tx[i].d = t[i];
425 + tx[i].skip = NULL;
426 + }
427
428 if (info->prev) {
429 strbuf_make_traverse_path(&base, info->prev,
@@ -506,10 +511,8 @@ int traverse_trees(struct index_state *istate,
511 if (mask & (1ul << i))
512 update_extended_entry(tx + i, entry + i);
513 }
509 - free(entry);
514 for (i = 0; i < n; i++)
515 free_extended_entry(tx + i);
512 - free(tx);
516 free(traverse_path);
517 info->traverse_path = NULL;
518 strbuf_release(&base);