]> git.ipfire.org Git - thirdparty/git.git/commitdiff
t5608: add regression test for >4GB object clone
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 8 May 2026 08:16:44 +0000 (08:16 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sat, 9 May 2026 02:25:32 +0000 (11:25 +0900)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t5608-clone-2gb.sh

index 87a8cd9f98381a868384f7af5d228d57e5613e2b..af93302ddec1cfa917edf95aa6e77fa8e3d85d36 100755 (executable)
@@ -49,4 +49,41 @@ test_expect_success 'clone - with worktree, file:// protocol' '
 
 '
 
+test_expect_success SIZE_T_IS_64BIT 'set up repo with >4GB object' '
+       large_blob_size=$((4*1024*1024*1024+1)) &&
+       git init --bare 4gb-repo &&
+       head_oid=$(test-tool synthesize pack \
+               --reachable-large "$large_blob_size" \
+               4gb-repo/objects/pack/test.pack) &&
+       git -C 4gb-repo index-pack objects/pack/test.pack &&
+       git -C 4gb-repo update-ref refs/heads/main $head_oid &&
+       git -C 4gb-repo symbolic-ref HEAD refs/heads/main
+'
+
+test_expect_success SIZE_T_IS_64BIT 'clone >4GB object via unpack-objects' '
+       # The synthesized pack has five objects, so a large unpack limit keeps
+       # fetch-pack on the unpack-objects path.
+       git -c fetch.unpackLimit=100 clone --bare \
+               "file://$(pwd)/4gb-repo" 4gb-clone-unpack &&
+
+       # Verify the large blob survived the clone by comparing its OID
+       # between source and clone.  We cannot use "cat-file -s" because
+       # object_info.sizep is still unsigned long, which truncates >4GB
+       # sizes on Windows.  OID equality proves content integrity since
+       # the clone already verified checksums via index-pack/unpack-objects.
+       source_blob=$(git -C 4gb-repo rev-parse main^:file) &&
+       clone_blob=$(git -C 4gb-clone-unpack rev-parse main^:file) &&
+       test "$source_blob" = "$clone_blob"
+'
+
+test_expect_success SIZE_T_IS_64BIT 'clone with >4GB object via index-pack' '
+       # Force fetch-pack to hand the pack to index-pack instead.
+       git -c fetch.unpackLimit=1 clone --bare \
+               "file://$(pwd)/4gb-repo" 4gb-clone-index &&
+
+       source_blob=$(git -C 4gb-repo rev-parse main^:file) &&
+       clone_blob=$(git -C 4gb-clone-index rev-parse main^:file) &&
+       test "$source_blob" = "$clone_blob"
+'
+
 test_done