summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2012-07-16 04:40:07 (GMT)
committerJunio C Hamano <gitster@pobox.com>2012-07-16 04:40:07 (GMT)
commit37b92a9a2eb1d49409a0b4d16404a3ac265ca723 (patch)
treec8f66838a633d8a9e988ad6fa0b4acc26babb082 /builtin
parentb9a0801ad0222256e2ddbf38d8bcce9f32e0211c (diff)
parentf8b090386bb5af172ea95f16ad6274e02222d2c1 (diff)
downloadgit-37b92a9a2eb1d49409a0b4d16404a3ac265ca723.zip
git-37b92a9a2eb1d49409a0b4d16404a3ac265ca723.tar.gz
git-37b92a9a2eb1d49409a0b4d16404a3ac265ca723.tar.bz2
Merge branch 'jk/index-pack-streaming-fix'
The streaming index-pack introduced in 1.7.11 had a data corruption bug, and this should fix it. * jk/index-pack-streaming-fix: index-pack: loop while inflating objects in unpack_data
Diffstat (limited to 'builtin')
-rw-r--r--builtin/index-pack.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index 5a0372a..953dd30 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -524,7 +524,6 @@ static void *unpack_data(struct object_entry *obj,
stream.avail_out = consume ? 64*1024 : obj->size;
do {
- unsigned char *last_out = stream.next_out;
ssize_t n = (len < 64*1024) ? len : 64*1024;
n = pread(pack_fd, inbuf, n, from);
if (n < 0)
@@ -538,15 +537,19 @@ static void *unpack_data(struct object_entry *obj,
len -= n;
stream.next_in = inbuf;
stream.avail_in = n;
- status = git_inflate(&stream, 0);
- if (consume) {
- if (consume(last_out, stream.next_out - last_out, cb_data)) {
- free(inbuf);
- free(data);
- return NULL;
- }
- stream.next_out = data;
- stream.avail_out = 64*1024;
+ if (!consume)
+ status = git_inflate(&stream, 0);
+ else {
+ do {
+ status = git_inflate(&stream, 0);
+ if (consume(data, stream.next_out - data, cb_data)) {
+ free(inbuf);
+ free(data);
+ return NULL;
+ }
+ stream.next_out = data;
+ stream.avail_out = 64*1024;
+ } while (status == Z_OK && stream.avail_in);
}
} while (len && status == Z_OK && !stream.avail_in);