fsck: check rev-index checksums
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>
Derrick Stolee committed
Apr 17, 2023 at 16:21 UTC
d975fe1fa57d57cfd21a97f96f4a94b99f50f2f4
2 files changed
+50
pack-revindex.c
+10
@@ -5,6 +5,7 @@
5
#include "packfile.h"
6
#include "config.h"
7
#include "midx.h"
8
+#include "csum-file.h"
9
10
struct revindex_entry {
11
off_t offset;
@@ -309,6 +310,15 @@ int load_pack_revindex(struct repository *r, struct packed_git *p)
310
*/
311
int verify_pack_revindex(struct packed_git *p)
312
{
313
+ /* Do not bother checking if not initialized. */
314
+ if (!p->revindex_map)
315
+ return 0;
316
+
317
+ if (!hashfile_checksum_valid((const unsigned char *)p->revindex_map, p->revindex_size)) {
318
+ error(_("invalid checksum"));
319
+ return -1;
320
+ }
321
+
322
return 0;
323
}
324
t/t5325-reverse-index.sh
+40
@@ -145,4 +145,44 @@ test_expect_success 'fsck succeeds on good rev-index' '
145
)
146
'
147
148
+test_expect_success 'set up rev-index corruption tests' '
149
+ git init corrupt &&
150
+ (
151
+ cd corrupt &&
152
+
153
+ test_commit commit &&
154
+ git -c pack.writeReverseIndex=true repack -ad &&
155
+
156
+ revfile=$(ls .git/objects/pack/pack-*.rev) &&
157
+ chmod a+w $revfile &&
158
+ cp $revfile $revfile.bak
159
+ )
160
+'
161
+
162
+corrupt_rev_and_verify () {
163
+ (
164
+ pos="$1" &&
165
+ value="$2" &&
166
+ error="$3" &&
167
+
168
+ cd corrupt &&
169
+ revfile=$(ls .git/objects/pack/pack-*.rev) &&
170
+
171
+ # Reset to original rev-file.
172
+ cp $revfile.bak $revfile &&
173
+
174
+ printf "$value" | dd of=$revfile bs=1 seek="$pos" conv=notrunc &&
175
+ test_must_fail git fsck 2>err &&
176
+ grep "$error" err
177
+ )
178
+}
179
+
180
+test_expect_success 'fsck catches invalid checksum' '
181
+ revfile=$(ls corrupt/.git/objects/pack/pack-*.rev) &&
182
+ orig_size=$(wc -c <$revfile) &&
183
+ hashpos=$((orig_size - 10)) &&
184
+ corrupt_rev_and_verify $hashpos bogus \
185
+ "invalid checksum"
186
+'
187
+
188
test_done