Skip to content
Permalink
090de6b289
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 179 lines (154 sloc) 5.19 KB
#!/bin/sh
test_description='bounds-checking of access to mmapped on-disk file formats'
. ./test-lib.sh
clear_base () {
test_when_finished 'restore_base' &&
rm -f $base
}
restore_base () {
cp base-backup/* .git/objects/pack/
}
do_pack () {
pack_objects=$1; shift
sha1=$(
for i in $pack_objects
do
echo $i
done | git pack-objects "$@" .git/objects/pack/pack
) &&
pack=.git/objects/pack/pack-$sha1.pack &&
idx=.git/objects/pack/pack-$sha1.idx &&
chmod +w $pack $idx &&
test_when_finished 'rm -f "$pack" "$idx"'
}
munge () {
printf "$3" | dd of="$1" bs=1 conv=notrunc seek=$2
}
# Offset in a v2 .idx to its initial and extended offset tables. For an index
# with "nr" objects, this is:
#
# magic(4) + version(4) + fan-out(4*256) + sha1s(20*nr) + crc(4*nr),
#
# for the initial, and another ofs(4*nr) past that for the extended.
#
ofs_table () {
echo $((4 + 4 + 4*256 + 20*$1 + 4*$1))
}
extended_table () {
echo $(($(ofs_table "$1") + 4*$1))
}
test_expect_success 'set up base packfile and variables' '
# the hash of this content starts with ff, which
# makes some later computations much simpler
echo 74 >file &&
git add file &&
git commit -m base &&
git repack -ad &&
base=$(echo .git/objects/pack/*) &&
chmod +w $base &&
mkdir base-backup &&
cp $base base-backup/ &&
object=$(git rev-parse HEAD:file)
'
test_expect_success 'pack/index object count mismatch' '
do_pack $object &&
munge $pack 8 "\377\0\0\0" &&
clear_base &&
# We enumerate the objects from the completely-fine
# .idx, but notice later that the .pack is bogus
# and fail to show any data.
echo "$object missing" >expect &&
git cat-file --batch-all-objects --batch-check >actual &&
test_cmp expect actual &&
# ...and here fail to load the object (without segfaulting),
# but fallback to a good copy if available.
test_must_fail git cat-file blob $object &&
restore_base &&
git cat-file blob $object >actual &&
test_cmp file actual &&
# ...and make sure that index-pack --verify, which has its
# own reading routines, does not segfault.
test_must_fail git index-pack --verify $pack
'
test_expect_success 'matched bogus object count' '
do_pack $object &&
munge $pack 8 "\377\0\0\0" &&
munge $idx $((255 * 4)) "\377\0\0\0" &&
clear_base &&
# Unlike above, we should notice early that the .idx is totally
# bogus, and not even enumerate its contents.
>expect &&
git cat-file --batch-all-objects --batch-check >actual &&
test_cmp expect actual &&
# But as before, we can do the same object-access checks.
test_must_fail git cat-file blob $object &&
restore_base &&
git cat-file blob $object >actual &&
test_cmp file actual &&
test_must_fail git index-pack --verify $pack
'
# Note that we cannot check the fallback case for these
# further .idx tests, as we notice the problem in functions
# whose interface doesn't allow an error return (like use_pack()),
# and thus we just die().
#
# There's also no point in doing enumeration tests, as
# we are munging offsets here, which are about looking up
# specific objects.
test_expect_success 'bogus object offset (v1)' '
do_pack $object --index-version=1 &&
munge $idx $((4 * 256)) "\377\0\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus object offset (v2, no msb)' '
do_pack $object --index-version=2 &&
munge $idx $(ofs_table 1) "\0\377\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus offset into v2 extended table' '
do_pack $object --index-version=2 &&
munge $idx $(ofs_table 1) "\377\0\0\0" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus offset inside v2 extended table' '
# We need two objects here, so we can plausibly require
# an extended table (if the first object were larger than 2^31).
do_pack "$object $(git rev-parse HEAD)" --index-version=2 &&
# We have to make extra room for the table, so we cannot
# just munge in place as usual.
{
dd if=$idx bs=1 count=$(($(ofs_table 2) + 4)) &&
printf "\200\0\0\0" &&
printf "\377\0\0\0\0\0\0\0" &&
dd if=$idx bs=1 skip=$(extended_table 2)
} >tmp &&
mv tmp "$idx" &&
clear_base &&
test_must_fail git cat-file blob $object &&
test_must_fail git index-pack --verify $pack
'
test_expect_success 'bogus OFS_DELTA in packfile' '
# Generate a pack with a delta in it.
base=$(test-genrandom foo 3000 | git hash-object --stdin -w) &&
delta=$(test-genrandom foo 2000 | git hash-object --stdin -w) &&
do_pack "$base $delta" --delta-base-offset &&
rm -f .git/objects/??/* &&
# Double check that we have the delta we expect.
echo $base >expect &&
echo $delta | git cat-file --batch-check="%(deltabase)" >actual &&
test_cmp expect actual &&
# Now corrupt it. We assume the varint size for the delta is small
# enough to fit in the first byte (which it should be, since it
# is a pure deletion from the base), and that original ofs_delta
# takes 2 bytes (which it should, as it should be ~3000).
ofs=$(git show-index <$idx | grep $delta | cut -d" " -f1) &&
munge $pack $(($ofs + 1)) "\177\377" &&
test_must_fail git cat-file blob $delta >/dev/null
'
test_done