Skip to content

Commit

Permalink
Merge branch 'tb/commit-graph-harden'
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Oct 7, 2019
2 parents ae203ba + 806278d commit 80693e3
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
11 changes: 9 additions & 2 deletions commit-graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 2 additions & 1 deletion commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
43 changes: 43 additions & 0 deletions t/t5318-commit-graph.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 80693e3

Please sign in to comment.