зеркало из https://github.com/microsoft/git.git
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
This commit is contained in:
Коммит
1f5d429e4a
22
tree-diff.c
22
tree-diff.c
|
@ -14,6 +14,16 @@
|
||||||
*/
|
*/
|
||||||
#define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ
|
#define S_IFXMIN_NEQ S_DIFFTREE_IFXMIN_NEQ
|
||||||
|
|
||||||
|
#define FAST_ARRAY_ALLOC(x, nr) do { \
|
||||||
|
if ((nr) <= 2) \
|
||||||
|
(x) = xalloca((nr) * sizeof(*(x))); \
|
||||||
|
else \
|
||||||
|
ALLOC_ARRAY((x), nr); \
|
||||||
|
} while(0)
|
||||||
|
#define FAST_ARRAY_FREE(x, nr) do { \
|
||||||
|
if ((nr) > 2) \
|
||||||
|
free((x)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
static struct combine_diff_path *ll_diff_tree_paths(
|
static struct combine_diff_path *ll_diff_tree_paths(
|
||||||
struct combine_diff_path *p, const unsigned char *sha1,
|
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,
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
const unsigned char **parents_sha1;
|
const unsigned char **parents_sha1;
|
||||||
|
|
||||||
parents_sha1 = xalloca(nparent * sizeof(parents_sha1[0]));
|
FAST_ARRAY_ALLOC(parents_sha1, nparent);
|
||||||
for (i = 0; i < nparent; ++i) {
|
for (i = 0; i < nparent; ++i) {
|
||||||
/* same rule as in emitthis */
|
/* same rule as in emitthis */
|
||||||
int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ);
|
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,
|
||||||
strbuf_add(base, path, pathlen);
|
strbuf_add(base, path, pathlen);
|
||||||
strbuf_addch(base, '/');
|
strbuf_addch(base, '/');
|
||||||
p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
|
p = ll_diff_tree_paths(p, sha1, parents_sha1, nparent, base, opt);
|
||||||
xalloca_free(parents_sha1);
|
FAST_ARRAY_FREE(parents_sha1, nparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
strbuf_setlen(base, old_baselen);
|
strbuf_setlen(base, old_baselen);
|
||||||
|
@ -402,8 +412,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
|
||||||
void *ttree, **tptree;
|
void *ttree, **tptree;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
tp = xalloca(nparent * sizeof(tp[0]));
|
FAST_ARRAY_ALLOC(tp, nparent);
|
||||||
tptree = xalloca(nparent * sizeof(tptree[0]));
|
FAST_ARRAY_ALLOC(tptree, nparent);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* load parents first, as they are probably already cached.
|
* load parents first, as they are probably already cached.
|
||||||
|
@ -531,8 +541,8 @@ static struct combine_diff_path *ll_diff_tree_paths(
|
||||||
free(ttree);
|
free(ttree);
|
||||||
for (i = nparent-1; i >= 0; i--)
|
for (i = nparent-1; i >= 0; i--)
|
||||||
free(tptree[i]);
|
free(tptree[i]);
|
||||||
xalloca_free(tptree);
|
FAST_ARRAY_FREE(tptree, nparent);
|
||||||
xalloca_free(tp);
|
FAST_ARRAY_FREE(tp, nparent);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче