@@ -266,26 +266,23 @@ static void unlink_base_data(struct base_data *c)
266
266
267
267
static void * unpack_entry_data (unsigned long offset , unsigned long size )
268
268
{
269
+ int status ;
269
270
z_stream stream ;
270
271
void * buf = xmalloc (size );
271
272
272
273
memset (& stream , 0 , sizeof (stream ));
274
+ git_inflate_init (& stream );
273
275
stream .next_out = buf ;
274
276
stream .avail_out = size ;
275
- stream .next_in = fill (1 );
276
- stream .avail_in = input_len ;
277
- git_inflate_init (& stream );
278
277
279
- for (;;) {
280
- int ret = git_inflate (& stream , 0 );
281
- use (input_len - stream .avail_in );
282
- if (stream .total_out == size && ret == Z_STREAM_END )
283
- break ;
284
- if (ret != Z_OK )
285
- bad_object (offset , "inflate returned %d" , ret );
278
+ do {
286
279
stream .next_in = fill (1 );
287
280
stream .avail_in = input_len ;
288
- }
281
+ status = git_inflate (& stream , 0 );
282
+ use (input_len - stream .avail_in );
283
+ } while (status == Z_OK );
284
+ if (stream .total_out != size || status != Z_STREAM_END )
285
+ bad_object (offset , "inflate returned %d" , status );
289
286
git_inflate_end (& stream );
290
287
return buf ;
291
288
}
@@ -359,34 +356,38 @@ static void *get_data_from_pack(struct object_entry *obj)
359
356
{
360
357
off_t from = obj [0 ].idx .offset + obj [0 ].hdr_size ;
361
358
unsigned long len = obj [1 ].idx .offset - from ;
362
- unsigned long rdy = 0 ;
363
- unsigned char * src , * data ;
359
+ unsigned char * data , * inbuf ;
364
360
z_stream stream ;
365
- int st ;
361
+ int status ;
366
362
367
- src = xmalloc (len );
368
- data = src ;
369
- do {
370
- ssize_t n = pread (pack_fd , data + rdy , len - rdy , from + rdy );
371
- if (n < 0 )
372
- die_errno ("cannot pread pack file" );
373
- if (!n )
374
- die ("premature end of pack file, %lu bytes missing" ,
375
- len - rdy );
376
- rdy += n ;
377
- } while (rdy < len );
378
363
data = xmalloc (obj -> size );
364
+ inbuf = xmalloc ((len < 64 * 1024 ) ? len : 64 * 1024 );
365
+
379
366
memset (& stream , 0 , sizeof (stream ));
367
+ git_inflate_init (& stream );
380
368
stream .next_out = data ;
381
369
stream .avail_out = obj -> size ;
382
- stream .next_in = src ;
383
- stream .avail_in = len ;
384
- git_inflate_init (& stream );
385
- while ((st = git_inflate (& stream , Z_FINISH )) == Z_OK );
386
- git_inflate_end (& stream );
387
- if (st != Z_STREAM_END || stream .total_out != obj -> size )
370
+
371
+ do {
372
+ ssize_t n = (len < 64 * 1024 ) ? len : 64 * 1024 ;
373
+ n = pread (pack_fd , inbuf , n , from );
374
+ if (n < 0 )
375
+ die_errno ("cannot pread pack file" );
376
+ if (!n )
377
+ die ("premature end of pack file, %lu bytes missing" , len );
378
+ from += n ;
379
+ len -= n ;
380
+ stream .next_in = inbuf ;
381
+ stream .avail_in = n ;
382
+ status = git_inflate (& stream , 0 );
383
+ } while (len && status == Z_OK && !stream .avail_in );
384
+
385
+ /* This has been inflated OK when first encountered, so... */
386
+ if (status != Z_STREAM_END || stream .total_out != obj -> size )
388
387
die ("serious inflate inconsistency" );
389
- free (src );
388
+
389
+ git_inflate_end (& stream );
390
+ free (inbuf );
390
391
return data ;
391
392
}
392
393
@@ -668,25 +669,25 @@ static void parse_pack_objects(unsigned char *sha1)
668
669
static int write_compressed (struct sha1file * f , void * in , unsigned int size )
669
670
{
670
671
z_stream stream ;
671
- unsigned long maxsize ;
672
- void * out ;
672
+ int status ;
673
+ unsigned char outbuf [ 4096 ] ;
673
674
674
675
memset (& stream , 0 , sizeof (stream ));
675
676
deflateInit (& stream , zlib_compression_level );
676
- maxsize = deflateBound (& stream , size );
677
- out = xmalloc (maxsize );
678
-
679
- /* Compress it */
680
677
stream .next_in = in ;
681
678
stream .avail_in = size ;
682
- stream .next_out = out ;
683
- stream .avail_out = maxsize ;
684
- while (deflate (& stream , Z_FINISH ) == Z_OK );
685
- deflateEnd (& stream );
686
679
680
+ do {
681
+ stream .next_out = outbuf ;
682
+ stream .avail_out = sizeof (outbuf );
683
+ status = deflate (& stream , Z_FINISH );
684
+ sha1write (f , outbuf , sizeof (outbuf ) - stream .avail_out );
685
+ } while (status == Z_OK );
686
+
687
+ if (status != Z_STREAM_END )
688
+ die ("unable to deflate appended object (%d)" , status );
687
689
size = stream .total_out ;
688
- sha1write (f , out , size );
689
- free (out );
690
+ deflateEnd (& stream );
690
691
return size ;
691
692
}
692
693
0 commit comments