summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/lib-httpd/apache.conf3
-rwxr-xr-xt/t0001-init.sh20
-rwxr-xr-xt/t5313-pack-bounds-checks.sh179
-rwxr-xr-xt/t5510-fetch.sh10
-rwxr-xr-xt/t9700/test.pl8
5 files changed, 204 insertions, 16 deletions
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 7d15e6d44c..f667e7ce2f 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -64,6 +64,9 @@ LockFile accept.lock
<IfModule !mod_mpm_prefork.c>
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
</IfModule>
+<IfModule !mod_unixd.c>
+ LoadModule unixd_module modules/mod_unixd.so
+</IfModule>
</IfVersion>
PassEnv GIT_VALGRIND
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 295aa5949a..a5b9e7a4c7 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -88,19 +88,17 @@ test_expect_success 'plain nested in bare through aliased command' '
'
test_expect_success 'No extra GIT_* on alias scripts' '
- (
- env | sed -ne "/^GIT_/s/=.*//p" &&
- echo GIT_PREFIX && # setup.c
- echo GIT_TEXTDOMAINDIR # wrapper-for-bin.sh
- ) | sort | uniq >expected &&
- cat <<-\EOF >script &&
- #!/bin/sh
- env | sed -ne "/^GIT_/s/=.*//p" | sort >actual
- exit 0
+ write_script script <<-\EOF &&
+ env |
+ sed -n \
+ -e "/^GIT_PREFIX=/d" \
+ -e "/^GIT_TEXTDOMAINDIR=/d" \
+ -e "/^GIT_/s/=.*//p" |
+ sort
EOF
- chmod 755 script &&
+ ./script >expected &&
git config alias.script \!./script &&
- ( mkdir sub && cd sub && git script ) &&
+ ( mkdir sub && cd sub && git script >../actual ) &&
test_cmp expected actual
'
diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh
new file mode 100755
index 0000000000..a8a587abc3
--- /dev/null
+++ b/t/t5313-pack-bounds-checks.sh
@@ -0,0 +1,179 @@
+#!/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
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 0c10c856a9..38321d19ef 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -679,10 +679,12 @@ test_expect_success 'fetching with auto-gc does not lock up' '
EOF
git clone "file://$D" auto-gc &&
test_commit test2 &&
- cd auto-gc &&
- git config gc.autoPackLimit 1 &&
- GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
- ! grep "Should I try again" fetch.out
+ (
+ cd auto-gc &&
+ git config gc.autoPackLimit 1 &&
+ GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
+ ! grep "Should I try again" fetch.out
+ )
'
test_done
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 7e8c40b97b..1b75c91965 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -17,6 +17,12 @@ BEGIN {
use Cwd;
use File::Basename;
+sub adjust_dirsep {
+ my $path = shift;
+ $path =~ s{\\}{/}g;
+ return $path;
+}
+
BEGIN { use_ok('Git') }
# set up
@@ -33,7 +39,7 @@ is($r->config_int("test.int"), 2048, "config_int: integer");
is($r->config_int("test.nonexistent"), undef, "config_int: nonexistent");
ok($r->config_bool("test.booltrue"), "config_bool: true");
ok(!$r->config_bool("test.boolfalse"), "config_bool: false");
-is($r->config_path("test.path") =~ s/\\/\//gr, $r->config("test.pathexpanded"),
+is(adjust_dirsep($r->config_path("test.path")), $r->config("test.pathexpanded"),
"config_path: ~/foo expansion");
is_deeply([$r->config_path("test.pathmulti")], ["foo", "bar"],
"config_path: multiple values");