]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'tb/commit-graph-harden'
authorJunio C Hamano <gitster@pobox.com>
Mon, 7 Oct 2019 02:32:58 +0000 (11:32 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Oct 2019 02:32:58 +0000 (11:32 +0900)
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

commit-graph.c
commit.c
t/t5318-commit-graph.sh

index c3ba79fe4e11f5b47cf05e29c68a868d29ade1f9..6ae2009a96ab4ffa3f508ee477056f718119210a 100644 (file)
@@ -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;
 
index 3fe5f8fa9c6e95e966bbebca3159e24595e1ee48..40890ae7ce8a48a2da06bcde6fc5a9db77260707 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -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)
index df3fed3a085e090960abfdd52ac235190be0cb8d..d42b3efe39183627aaeb3eef461e6593dd762e4a 100755 (executable)
@@ -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