1
0
mirror of https://github.com/git/git synced 2024-07-08 20:06:13 +00:00

fsck: handle NULL return of lookup_blob() and lookup_tree()

lookup_blob() and lookup_tree() can return NULL if they find an object
of an unexpected type.  Accessing the object member is undefined in that
case.  Cast the result to a struct object pointer instead; we can do
that because object is the first member of all object types.  This trick
is already used in other places in the code.

An error message is already shown by object_as_type(), which is called
by the lookup functions.  The walk callback functions are expected to
handle NULL object pointers passed to them, but put_object_name() needs
a valid object, so avoid calling it without one.

Suggested-by: SZEDER Gábor <szeder.dev@gmail.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
René Scharfe 2017-10-05 21:41:26 +02:00 committed by Junio C Hamano
parent 4010f1d1b7
commit 2720f6db5d
2 changed files with 26 additions and 4 deletions

8
fsck.c
View File

@ -358,15 +358,15 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op
continue;
if (S_ISDIR(entry.mode)) {
obj = &lookup_tree(entry.oid)->object;
if (name)
obj = (struct object *)lookup_tree(entry.oid);
if (name && obj)
put_object_name(options, obj, "%s%s/", name,
entry.path);
result = options->walk(obj, OBJ_TREE, data, options);
}
else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) {
obj = &lookup_blob(entry.oid)->object;
if (name)
obj = (struct object *)lookup_blob(entry.oid);
if (name && obj)
put_object_name(options, obj, "%s%s", name,
entry.path);
result = options->walk(obj, OBJ_BLOB, data, options);

View File

@ -222,6 +222,28 @@ test_expect_success 'unparseable tree object' '
test_i18ngrep ! "fatal: empty filename in tree entry" out
'
hex2oct() {
perl -ne 'printf "\\%03o", hex for /../g'
}
test_expect_success 'tree entry with type mismatch' '
test_when_finished "remove_object \$blob" &&
test_when_finished "remove_object \$tree" &&
test_when_finished "remove_object \$commit" &&
test_when_finished "git update-ref -d refs/heads/type_mismatch" &&
blob=$(echo blob | git hash-object -w --stdin) &&
blob_bin=$(echo $blob | hex2oct) &&
tree=$(
printf "40000 dir\0${blob_bin}100644 file\0${blob_bin}" |
git hash-object -t tree --stdin -w --literally
) &&
commit=$(git commit-tree $tree) &&
git update-ref refs/heads/type_mismatch $commit &&
test_must_fail git fsck >out 2>&1 &&
test_i18ngrep "is a blob, not a tree" out &&
test_i18ngrep ! "dangling blob" out
'
test_expect_success 'tag pointing to nonexistent' '
cat >invalid-tag <<-\EOF &&
object ffffffffffffffffffffffffffffffffffffffff