Skip to content

Commit 806278d

Browse files
ttaylorrgitster
authored andcommitted
commit-graph.c: handle corrupt/missing trees
Apply similar treatment as in the previous commit to handle an unchecked call to 'get_commit_tree_oid()'. Previously, a NULL return value from this function would be immediately dereferenced with '->hash', and then cause a segfault. Before dereferencing to access the 'hash' member, check the return value of 'get_commit_tree_oid()' to make sure that it is not NULL. To make this check correct, a related change is also needed in 'commit.c', which is to check the return value of 'get_commit_tree' before taking its address. If 'get_commit_tree' returns NULL, we encounter an undefined behavior when taking the address of the return value of 'get_commit_tree' and then taking '->object.oid'. (On my system, this is memory address 0x8, which is obviously wrong). Fix this by making sure that 'get_commit_tree' returns something non-NULL before digging through a structure that is not there, thus preventing a segfault down the line in the commit graph code. Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 16749b8 commit 806278d

File tree

3 files changed

+9
-3
lines changed

3 files changed

+9
-3
lines changed

commit-graph.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,14 +839,19 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
839839

840840
while (list < last) {
841841
struct commit_list *parent;
842+
struct object_id *tree;
842843
int edge_value;
843844
uint32_t packedDate[2];
844845
display_progress(ctx->progress, ++ctx->progress_cnt);
845846

846847
if (parse_commit_no_graph(*list))
847848
die(_("unable to parse commit %s"),
848849
oid_to_hex(&(*list)->object.oid));
849-
hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len);
850+
tree = get_commit_tree_oid(*list);
851+
if (!tree)
852+
die(_("unable to get tree for %s"),
853+
oid_to_hex(&(*list)->object.oid));
854+
hashwrite(f, tree->hash, hash_len);
850855

851856
parent = (*list)->parents;
852857

commit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,8 @@ struct tree *repo_get_commit_tree(struct repository *r,
358358

359359
struct object_id *get_commit_tree_oid(const struct commit *commit)
360360
{
361-
return &get_commit_tree(commit)->object.oid;
361+
struct tree *tree = get_commit_tree(commit);
362+
return tree ? &tree->object.oid : NULL;
362363
}
363364

364365
void release_commit_memory(struct parsed_object_pool *pool, struct commit *c)

t/t5318-commit-graph.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ test_expect_success 'corrupt commit-graph write (broken parent)' '
607607
)
608608
'
609609

610-
test_expect_failure 'corrupt commit-graph write (missing tree)' '
610+
test_expect_success 'corrupt commit-graph write (missing tree)' '
611611
rm -rf repo &&
612612
git init repo &&
613613
(

0 commit comments

Comments
 (0)