Skip to content

Commit ee64e34

Browse files
committed
Merge branch 'jk/unpack-entry-fallback-to-another'
* jk/unpack-entry-fallback-to-another: unpack_entry: do not die when we fail to apply a delta t5303: drop "count=1" from corruption dd
2 parents 23983a4 + 1ee886c commit ee64e34

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

sha1_file.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2145,8 +2145,17 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
21452145
data = patch_delta(base, base_size,
21462146
delta_data, delta_size,
21472147
&size);
2148+
2149+
/*
2150+
* We could not apply the delta; warn the user, but keep going.
2151+
* Our failure will be noticed either in the next iteration of
2152+
* the loop, or if this is the final delta, in the caller when
2153+
* we return NULL. Those code paths will take care of making
2154+
* a more explicit warning and retrying with another copy of
2155+
* the object.
2156+
*/
21482157
if (!data)
2149-
die("failed to apply delta");
2158+
error("failed to apply delta");
21502159

21512160
free(delta_data);
21522161
}

t/t5303-pack-corruption-resilience.sh

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ do_corrupt_object() {
5151
ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` &&
5252
ofs=$(($ofs + $2)) &&
5353
chmod +w ${pack}.pack &&
54-
dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs &&
54+
dd of=${pack}.pack bs=1 conv=notrunc seek=$ofs &&
5555
test_must_fail git verify-pack ${pack}.pack
5656
}
5757

@@ -275,6 +275,33 @@ test_expect_success \
275275
git cat-file blob $blob_2 > /dev/null &&
276276
git cat-file blob $blob_3 > /dev/null'
277277

278+
test_expect_success \
279+
'corruption of delta base reference pointing to wrong object' \
280+
'create_new_pack --delta-base-offset &&
281+
git prune-packed &&
282+
printf "\220\033" | do_corrupt_object $blob_3 2 &&
283+
git cat-file blob $blob_1 >/dev/null &&
284+
git cat-file blob $blob_2 >/dev/null &&
285+
test_must_fail git cat-file blob $blob_3 >/dev/null'
286+
287+
test_expect_success \
288+
'... but having a loose copy allows for full recovery' \
289+
'mv ${pack}.idx tmp &&
290+
git hash-object -t blob -w file_3 &&
291+
mv tmp ${pack}.idx &&
292+
git cat-file blob $blob_1 > /dev/null &&
293+
git cat-file blob $blob_2 > /dev/null &&
294+
git cat-file blob $blob_3 > /dev/null'
295+
296+
test_expect_success \
297+
'... and then a repack "clears" the corruption' \
298+
'do_repack --delta-base-offset --no-reuse-delta &&
299+
git prune-packed &&
300+
git verify-pack ${pack}.pack &&
301+
git cat-file blob $blob_1 > /dev/null &&
302+
git cat-file blob $blob_2 > /dev/null &&
303+
git cat-file blob $blob_3 > /dev/null'
304+
278305
test_expect_success \
279306
'corrupting header to have too small output buffer fails unpack' \
280307
'create_new_pack &&

0 commit comments

Comments
 (0)