diff options
author | Jeff King <peff@peff.net> | 2023-08-31 08:22:08 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-09-01 00:51:08 +0200 |
commit | 7b61bd18b13223064db01d89e3b8af106661efd5 (patch) | |
tree | a141fa6fa4bd6fad3ded7cb5b52aaaa12d64e2d4 /tree-diff.c | |
parent | list-objects: respect max_allowed_tree_depth (diff) | |
download | git-7b61bd18b13223064db01d89e3b8af106661efd5.tar.xz git-7b61bd18b13223064db01d89e3b8af106661efd5.zip |
tree-diff: respect max_allowed_tree_depth
When diffing trees, we recurse to handle subtrees. That means we may run
out of stack space and segfault. Let's teach this code path about
core.maxTreeDepth in order to fail more gracefully.
As with the previous patch, we have no way to return an error (and other
tree-loading problems would just cause us to die()). So we'll likewise
call die() if we exceed the maximum depth.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'tree-diff.c')
-rw-r--r-- | tree-diff.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/tree-diff.c b/tree-diff.c index 8fc159b86e..46107772d1 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -7,6 +7,7 @@ #include "hash.h" #include "tree.h" #include "tree-walk.h" +#include "environment.h" /* * Some mode bits are also used internally for computations. @@ -45,7 +46,8 @@ static struct combine_diff_path *ll_diff_tree_paths( struct combine_diff_path *p, const struct object_id *oid, const struct object_id **parents_oid, int nparent, - struct strbuf *base, struct diff_options *opt); + struct strbuf *base, struct diff_options *opt, + int depth); static void ll_diff_tree_oid(const struct object_id *old_oid, const struct object_id *new_oid, struct strbuf *base, struct diff_options *opt); @@ -196,7 +198,7 @@ static struct combine_diff_path *path_appendnew(struct combine_diff_path *last, static struct combine_diff_path *emit_path(struct combine_diff_path *p, struct strbuf *base, struct diff_options *opt, int nparent, struct tree_desc *t, struct tree_desc *tp, - int imin) + int imin, int depth) { unsigned short mode; const char *path; @@ -302,7 +304,8 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, strbuf_add(base, path, pathlen); strbuf_addch(base, '/'); - p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt); + p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt, + depth + 1); FAST_ARRAY_FREE(parents_oid, nparent); } @@ -423,12 +426,16 @@ static inline void update_tp_entries(struct tree_desc *tp, int nparent) static struct combine_diff_path *ll_diff_tree_paths( struct combine_diff_path *p, const struct object_id *oid, const struct object_id **parents_oid, int nparent, - struct strbuf *base, struct diff_options *opt) + struct strbuf *base, struct diff_options *opt, + int depth) { struct tree_desc t, *tp; void *ttree, **tptree; int i; + if (depth > max_allowed_tree_depth) + die("exceeded maximum allowed tree depth"); + FAST_ARRAY_ALLOC(tp, nparent); FAST_ARRAY_ALLOC(tptree, nparent); @@ -522,7 +529,7 @@ static struct combine_diff_path *ll_diff_tree_paths( /* D += {δ(t,pi) if pi=p[imin]; "+a" if pi > p[imin]} */ p = emit_path(p, base, opt, nparent, - &t, tp, imin); + &t, tp, imin, depth); skip_emit_t_tp: /* t↓, ∀ pi=p[imin] pi↓ */ @@ -534,7 +541,7 @@ static struct combine_diff_path *ll_diff_tree_paths( else if (cmp < 0) { /* D += "+t" */ p = emit_path(p, base, opt, nparent, - &t, /*tp=*/NULL, -1); + &t, /*tp=*/NULL, -1, depth); /* t↓ */ update_tree_entry(&t); @@ -550,7 +557,7 @@ static struct combine_diff_path *ll_diff_tree_paths( } p = emit_path(p, base, opt, nparent, - /*t=*/NULL, tp, imin); + /*t=*/NULL, tp, imin, depth); skip_emit_tp: /* ∀ pi=p[imin] pi↓ */ @@ -572,7 +579,7 @@ struct combine_diff_path *diff_tree_paths( const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt) { - p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt); + p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt, 0); /* * free pre-allocated last element, if any |