Skip to content

Commit b2dbf97

Browse files
pks-tgitster
authored andcommitted
builtin/index-pack: fix segfaults when running outside of a repo
It was reported that git-verify-pack(1) has started to crash with Git v2.46.0 when run outside of a repository. This is another fallout from c8aed5e (repository: stop setting SHA1 as the default object hash, 2024-05-07), where we have stopped setting the default hash algorithm for `the_repository`. Consequently, code that relies on `the_hash_algo` will now crash when it hasn't explicitly been initialized, which may be the case when running outside of a Git repository. The crash is not in git-verify-pack(1) but instead in git-index-pack(1), which gets called by the former. Ideally, both of these programs should be able to identify the hash algorithm used by the packfile and index without having to rely on external information. But unfortunately, the format for neither of them is completely self-describing, so it is not possible to derive that information. This is a design issue that we should address by introducing a new packfile version that encodes its object hash. For now though the more important fix is to not make either of these programs crash anymore, which we do by falling back to SHA1 when the object hash is unconfigured. This pessimizes reading packfiles which use a different hash than SHA1, but restores previous behaviour. Reported-by: Ilya K <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 39bf06a commit b2dbf97

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

builtin/index-pack.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,15 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
18681868
if (!index_name && pack_name)
18691869
index_name = derive_filename(pack_name, "pack", "idx", &index_name_buf);
18701870

1871+
/*
1872+
* Packfiles and indices do not carry enough information to be able to
1873+
* identify their object hash. So when we are neither in a repository
1874+
* nor has the user told us which object hash to use we have no other
1875+
* choice but to guess the object hash.
1876+
*/
1877+
if (!the_repository->hash_algo)
1878+
repo_set_hash_algo(the_repository, GIT_HASH_SHA1);
1879+
18711880
opts.flags &= ~(WRITE_REV | WRITE_REV_VERIFY);
18721881
if (rev_index) {
18731882
opts.flags |= verify ? WRITE_REV_VERIFY : WRITE_REV;

t/t5300-pack-object.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,4 +635,43 @@ test_expect_success 'negative window clamps to 0' '
635635
check_deltas stderr = 0
636636
'
637637

638+
for hash in sha1 sha256
639+
do
640+
test_expect_success "verify-pack with $hash packfile" '
641+
test_when_finished "rm -rf repo" &&
642+
git init --object-format=$hash repo &&
643+
test_commit -C repo initial &&
644+
git -C repo repack -ad &&
645+
git -C repo verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
646+
if test $hash = sha1
647+
then
648+
nongit git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx
649+
else
650+
# We have no way to identify the hash used by packfiles
651+
# or indices, so we always fall back to SHA1.
652+
nongit test_must_fail git verify-pack "$(pwd)"/repo/.git/objects/pack/*.idx &&
653+
# But with an explicit object format we should succeed.
654+
nongit git verify-pack --object-format=$hash "$(pwd)"/repo/.git/objects/pack/*.idx
655+
fi
656+
'
657+
658+
test_expect_success "index-pack outside of a $hash repository" '
659+
test_when_finished "rm -rf repo" &&
660+
git init --object-format=$hash repo &&
661+
test_commit -C repo initial &&
662+
git -C repo repack -ad &&
663+
git -C repo index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack &&
664+
if test $hash = sha1
665+
then
666+
nongit git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack
667+
else
668+
# We have no way to identify the hash used by packfiles
669+
# or indices, so we always fall back to SHA1.
670+
nongit test_must_fail git index-pack --verify "$(pwd)"/repo/.git/objects/pack/*.pack 2>err &&
671+
# But with an explicit object format we should succeed.
672+
nongit git index-pack --object-format=$hash --verify "$(pwd)"/repo/.git/objects/pack/*.pack
673+
fi
674+
'
675+
done
676+
638677
test_done

0 commit comments

Comments
 (0)