summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-10-14 16:10:37 -0700
committerJunio C Hamano <gitster@pobox.com>2009-10-14 16:10:37 -0700
commit695f9523ddfa0a2b8325507b4f077b073d8f438f (patch)
tree007e445a49deb60ab1fbdb886a202590cd1837a1
parent18a536476e68349bacab7ddf84166a907dd0bede (diff)
parentb3118bdc91876cbc04b7e81dcf7bea71d86ce4f8 (diff)
downloadgit-695f9523ddfa0a2b8325507b4f077b073d8f438f.tar.gz
Merge branch 'maint'
* maint: sha1_file: Fix infinite loop when pack is corrupted
-rw-r--r--sha1_file.c4
-rwxr-xr-xt/t5303-pack-corruption-resilience.sh9
2 files changed, 13 insertions, 0 deletions
diff --git a/sha1_file.c b/sha1_file.c
index 4ea0b18d0a..4cc8939e4b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1357,6 +1357,8 @@ unsigned long get_size_from_delta(struct packed_git *p,
in = use_pack(p, w_curs, curpos, &stream.avail_in);
stream.next_in = in;
st = git_inflate(&stream, Z_FINISH);
+ if (st == Z_BUF_ERROR && (stream.avail_in || !stream.avail_out))
+ break;
curpos += stream.next_in - in;
} while ((st == Z_OK || st == Z_BUF_ERROR) &&
stream.total_out < sizeof(delta_head));
@@ -1594,6 +1596,8 @@ static void *unpack_compressed_entry(struct packed_git *p,
in = use_pack(p, w_curs, curpos, &stream.avail_in);
stream.next_in = in;
st = git_inflate(&stream, Z_FINISH);
+ if (st == Z_BUF_ERROR && (stream.avail_in || !stream.avail_out))
+ break;
curpos += stream.next_in - in;
} while (st == Z_OK || st == Z_BUF_ERROR);
git_inflate_end(&stream);
diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh
index 5132d41309..5f6cd4f333 100755
--- a/t/t5303-pack-corruption-resilience.sh
+++ b/t/t5303-pack-corruption-resilience.sh
@@ -275,4 +275,13 @@ test_expect_success \
git cat-file blob $blob_2 > /dev/null &&
git cat-file blob $blob_3 > /dev/null'
+test_expect_success \
+ 'corrupting header to have too small output buffer fails unpack' \
+ 'create_new_pack &&
+ git prune-packed &&
+ printf "\262\001" | do_corrupt_object $blob_1 0 &&
+ test_must_fail git cat-file blob $blob_1 > /dev/null &&
+ test_must_fail git cat-file blob $blob_2 > /dev/null &&
+ test_must_fail git cat-file blob $blob_3 > /dev/null'
+
test_done