diff options
author | Junio C Hamano <gitster@pobox.com> | 2019-10-07 11:32:58 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2019-10-07 11:32:58 +0900 |
commit | 80693e3f09ab80cfe4a5a83467e765626ad0b15a (patch) | |
tree | 1100110f21941cbe7510a43d41c8121d59761030 | |
parent | Merge branch 'jt/cache-tree-avoid-lazy-fetch-during-merge' (diff) | |
parent | commit-graph.c: handle corrupt/missing trees (diff) | |
download | tgif-80693e3f09ab80cfe4a5a83467e765626ad0b15a.tar.xz |
Merge branch 'tb/commit-graph-harden'
The code to parse and use the commit-graph file has been made more
robust against corrupted input.
* tb/commit-graph-harden:
commit-graph.c: handle corrupt/missing trees
commit-graph.c: handle commit parsing errors
t/t5318: introduce failing 'git commit-graph write' tests
-rw-r--r-- | commit-graph.c | 11 | ||||
-rw-r--r-- | commit.c | 3 | ||||
-rwxr-xr-x | t/t5318-commit-graph.sh | 43 |
3 files changed, 54 insertions, 3 deletions
diff --git a/commit-graph.c b/commit-graph.c index c3ba79fe4e..6ae2009a96 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -846,12 +846,19 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len, while (list < last) { struct commit_list *parent; + struct object_id *tree; int edge_value; uint32_t packedDate[2]; display_progress(ctx->progress, ++ctx->progress_cnt); - parse_commit_no_graph(*list); - hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len); + if (parse_commit_no_graph(*list)) + die(_("unable to parse commit %s"), + oid_to_hex(&(*list)->object.oid)); + tree = get_commit_tree_oid(*list); + if (!tree) + die(_("unable to get tree for %s"), + oid_to_hex(&(*list)->object.oid)); + hashwrite(f, tree->hash, hash_len); parent = (*list)->parents; @@ -358,7 +358,8 @@ struct tree *repo_get_commit_tree(struct repository *r, struct object_id *get_commit_tree_oid(const struct commit *commit) { - return &get_commit_tree(commit)->object.oid; + struct tree *tree = get_commit_tree(commit); + return tree ? &tree->object.oid : NULL; } void release_commit_memory(struct parsed_object_pool *pool, struct commit *c) diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index df3fed3a08..d42b3efe39 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -621,4 +621,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' test_cmp expect actual ' +test_expect_success 'corrupt commit-graph write (broken parent)' ' + rm -rf repo && + git init repo && + ( + cd repo && + empty="$(git mktree </dev/null)" && + cat >broken <<-EOF && + tree $empty + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good commit" "$empty" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to parse commit" test_err + ) +' + +test_expect_success 'corrupt commit-graph write (missing tree)' ' + rm -rf repo && + git init repo && + ( + cd repo && + tree="$(git mktree </dev/null)" && + cat >broken <<-EOF && + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good" "$tree" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to get tree for" test_err + ) +' + test_done |