]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fsck: check rev-index checksums
authorDerrick Stolee <derrickstolee@github.com>
Mon, 17 Apr 2023 16:21:39 +0000 (16:21 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 17 Apr 2023 21:39:04 +0000 (14:39 -0700)
The previous change added calls to verify_pack_revindex() in
builtin/fsck.c, but the implementation of the method was left empty. Add
the first and most-obvious check to this method: checksum verification.

While here, create a helper method in the test script that makes it easy
to adjust the .rev file and check that 'git fsck' reports the correct
error message.

Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
pack-revindex.c
t/t5325-reverse-index.sh

index c3f2aaa3fea5ea99fce495645930f6fecd485be5..007a806994fd606984f9b28c51a61eee16bc9140 100644 (file)
@@ -5,6 +5,7 @@
 #include "packfile.h"
 #include "config.h"
 #include "midx.h"
+#include "csum-file.h"
 
 struct revindex_entry {
        off_t offset;
@@ -309,6 +310,15 @@ int load_pack_revindex(struct repository *r, struct packed_git *p)
  */
 int verify_pack_revindex(struct packed_git *p)
 {
+       /* Do not bother checking if not initialized. */
+       if (!p->revindex_map)
+               return 0;
+
+       if (!hashfile_checksum_valid((const unsigned char *)p->revindex_map, p->revindex_size)) {
+               error(_("invalid checksum"));
+               return -1;
+       }
+
        return 0;
 }
 
index 206c412f50baf1871985d45fd39e0ca470b6a126..6b7c709a1f6706e80f4835389785a1a7911b5ae7 100755 (executable)
@@ -145,4 +145,44 @@ test_expect_success 'fsck succeeds on good rev-index' '
        )
 '
 
+test_expect_success 'set up rev-index corruption tests' '
+       git init corrupt &&
+       (
+               cd corrupt &&
+
+               test_commit commit &&
+               git -c pack.writeReverseIndex=true repack -ad &&
+
+               revfile=$(ls .git/objects/pack/pack-*.rev) &&
+               chmod a+w $revfile &&
+               cp $revfile $revfile.bak
+       )
+'
+
+corrupt_rev_and_verify () {
+       (
+               pos="$1" &&
+               value="$2" &&
+               error="$3" &&
+
+               cd corrupt &&
+               revfile=$(ls .git/objects/pack/pack-*.rev) &&
+
+               # Reset to original rev-file.
+               cp $revfile.bak $revfile &&
+
+               printf "$value" | dd of=$revfile bs=1 seek="$pos" conv=notrunc &&
+               test_must_fail git fsck 2>err &&
+               grep "$error" err
+       )
+}
+
+test_expect_success 'fsck catches invalid checksum' '
+       revfile=$(ls corrupt/.git/objects/pack/pack-*.rev) &&
+       orig_size=$(wc -c <$revfile) &&
+       hashpos=$((orig_size - 10)) &&
+       corrupt_rev_and_verify $hashpos bogus \
+               "invalid checksum"
+'
+
 test_done