Merge branch 'jk/index-pack-streaming-fix'
authorJunio C Hamano <gitster@pobox.com>
Mon, 16 Jul 2012 04:40:07 +0000 (21:40 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 16 Jul 2012 04:40:07 +0000 (21:40 -0700)
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

1  2 
builtin/index-pack.c
diff --combined builtin/index-pack.c
index 5a0372ab08e7d7fe8381356669702b5e5838f78f,50d38767b1275849bb000ec7da4c487d187ad77f..953dd3004e285ce7aa0432f4fe0eacb0d0c2c887
@@@ -40,8 -40,8 +40,8 @@@ struct base_data 
        int ofs_first, ofs_last;
  };
  
 -#if !defined(NO_PTHREADS) && defined(NO_PREAD)
 -/* NO_PREAD uses compat/pread.c, which is not thread-safe. Disable threading. */
 +#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD)
 +/* pread() emulation is not thread-safe. Disable threading. */
  #define NO_PTHREADS
  #endif
  
@@@ -524,7 -524,6 +524,6 @@@ static void *unpack_data(struct object_
        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)
                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);