Skip to content

Commit a301988

Browse files
committed
t5608: add regression test for >4GB object clone
The shift overflow bug in index-pack and unpack-objects caused incorrect object size calculation when the encoded size required more than 32 bits of shift. This would result in corrupted or failed unpacking of objects larger than 4GB. Add a test that creates a pack file containing a 4GB+ blob using the new 'test-tool synthesize pack --reachable-large' command, then clones the repository to verify the fix works correctly. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent afa74a3 commit a301988

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

t/t5608-clone-2gb.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,41 @@ test_expect_success 'clone - with worktree, file:// protocol' '
4949
5050
'
5151

52+
test_expect_success SIZE_T_IS_64BIT 'set up repo with >4GB object' '
53+
large_blob_size=$((4*1024*1024*1024+1)) &&
54+
git init --bare 4gb-repo &&
55+
head_oid=$(test-tool synthesize pack \
56+
--reachable-large "$large_blob_size" \
57+
4gb-repo/objects/pack/test.pack) &&
58+
git -C 4gb-repo index-pack objects/pack/test.pack &&
59+
git -C 4gb-repo update-ref refs/heads/main $head_oid &&
60+
git -C 4gb-repo symbolic-ref HEAD refs/heads/main
61+
'
62+
63+
test_expect_success SIZE_T_IS_64BIT 'clone >4GB object via unpack-objects' '
64+
# The synthesized pack has five objects, so a large unpack limit keeps
65+
# fetch-pack on the unpack-objects path.
66+
git -c fetch.unpackLimit=100 clone --bare \
67+
"file://$(pwd)/4gb-repo" 4gb-clone-unpack &&
68+
69+
# Verify the large blob survived the clone by comparing its OID
70+
# between source and clone. We cannot use "cat-file -s" because
71+
# object_info.sizep is still unsigned long, which truncates >4GB
72+
# sizes on Windows. OID equality proves content integrity since
73+
# the clone already verified checksums via index-pack/unpack-objects.
74+
source_blob=$(git -C 4gb-repo rev-parse main^:file) &&
75+
clone_blob=$(git -C 4gb-clone-unpack rev-parse main^:file) &&
76+
test "$source_blob" = "$clone_blob"
77+
'
78+
79+
test_expect_success SIZE_T_IS_64BIT 'clone with >4GB object via index-pack' '
80+
# Force fetch-pack to hand the pack to index-pack instead.
81+
git -c fetch.unpackLimit=1 clone --bare \
82+
"file://$(pwd)/4gb-repo" 4gb-clone-index &&
83+
84+
source_blob=$(git -C 4gb-repo rev-parse main^:file) &&
85+
clone_blob=$(git -C 4gb-clone-index rev-parse main^:file) &&
86+
test "$source_blob" = "$clone_blob"
87+
'
88+
5289
test_done

0 commit comments

Comments
 (0)