Skip to content

Commit 1f5d429

Browse files
committed
Merge branch 'jk/avoid-unbounded-alloca' into maint
A codepath that used alloca(3) to place an unbounded amount of data on the stack has been updated to avoid doing so. * jk/avoid-unbounded-alloca: tree-diff: avoid alloca for large allocations
2 parents c014445 + b8ba412 commit 1f5d429

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

tree-diff.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
*/
1515
#define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ
1616

17+
#define FAST_ARRAY_ALLOC(x, nr) do { \
18+
if ((nr) <= 2) \
19+
(x) = xalloca((nr) * sizeof(*(x))); \
20+
else \
21+
ALLOC_ARRAY((x), nr); \
22+
} while(0)
23+
#define FAST_ARRAY_FREE(x, nr) do { \
24+
if ((nr) > 2) \
25+
free((x)); \
26+
} while(0)
1727

1828
static struct combine_diff_path *ll_diff_tree_paths(
1929
struct combine_diff_path *p, const unsigned char *sha1,
@@ -265,7 +275,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
265275
if (recurse) {
266276
const unsigned char **parents_sha1;
267277

268-
parents_sha1 = xalloca(nparent * sizeof(parents_sha1[0]));
278+
FAST_ARRAY_ALLOC(parents_sha1, nparent);
269279
for (i = 0; i < nparent; ++i) {
270280
/* same rule as in emitthis */
271281
int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
@@ -277,7 +287,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p,
277287
strbuf_add(base, path, pathlen);
278288
strbuf_addch(base, '/');
279289
p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
280-
xalloca_free(parents_sha1);
290+
FAST_ARRAY_FREE(parents_sha1, nparent);
281291
}
282292

283293
strbuf_setlen(base, old_baselen);
@@ -402,8 +412,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
402412
void *ttree, **tptree;
403413
int i;
404414

405-
tp = xalloca(nparent * sizeof(tp[0]));
406-
tptree = xalloca(nparent * sizeof(tptree[0]));
415+
FAST_ARRAY_ALLOC(tp, nparent);
416+
FAST_ARRAY_ALLOC(tptree, nparent);
407417

408418
/*
409419
* load parents first, as they are probably already cached.
@@ -531,8 +541,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
531541
free(ttree);
532542
for (i = nparent-1; i >= 0; i--)
533543
free(tptree[i]);
534-
xalloca_free(tptree);
535-
xalloca_free(tp);
544+
FAST_ARRAY_FREE(tptree, nparent);
545+
FAST_ARRAY_FREE(tp, nparent);
536546

537547
return p;
538548
}

0 commit comments

Comments
 (0)