@@ -504,23 +504,26 @@ static void *unpack_raw_entry(struct object_entry *obj,
504504 return data ;
505505}
506506
507- static void * get_data_from_pack (struct object_entry * obj )
507+ static void * unpack_data (struct object_entry * obj ,
508+ int (* consume )(const unsigned char * , unsigned long , void * ),
509+ void * cb_data )
508510{
509511 off_t from = obj [0 ].idx .offset + obj [0 ].hdr_size ;
510512 unsigned long len = obj [1 ].idx .offset - from ;
511513 unsigned char * data , * inbuf ;
512514 git_zstream stream ;
513515 int status ;
514516
515- data = xmalloc (obj -> size );
517+ data = xmalloc (consume ? 64 * 1024 : obj -> size );
516518 inbuf = xmalloc ((len < 64 * 1024 ) ? len : 64 * 1024 );
517519
518520 memset (& stream , 0 , sizeof (stream ));
519521 git_inflate_init (& stream );
520522 stream .next_out = data ;
521- stream .avail_out = obj -> size ;
523+ stream .avail_out = consume ? 64 * 1024 : obj -> size ;
522524
523525 do {
526+ unsigned char * last_out = stream .next_out ;
524527 ssize_t n = (len < 64 * 1024 ) ? len : 64 * 1024 ;
525528 n = pread (pack_fd , inbuf , n , from );
526529 if (n < 0 )
@@ -535,6 +538,15 @@ static void *get_data_from_pack(struct object_entry *obj)
535538 stream .next_in = inbuf ;
536539 stream .avail_in = n ;
537540 status = git_inflate (& stream , 0 );
541+ if (consume ) {
542+ if (consume (last_out , stream .next_out - last_out , cb_data )) {
543+ free (inbuf );
544+ free (data );
545+ return NULL ;
546+ }
547+ stream .next_out = data ;
548+ stream .avail_out = 64 * 1024 ;
549+ }
538550 } while (len && status == Z_OK && !stream .avail_in );
539551
540552 /* This has been inflated OK when first encountered, so... */
@@ -543,9 +555,18 @@ static void *get_data_from_pack(struct object_entry *obj)
543555
544556 git_inflate_end (& stream );
545557 free (inbuf );
558+ if (consume ) {
559+ free (data );
560+ data = NULL ;
561+ }
546562 return data ;
547563}
548564
565+ static void * get_data_from_pack (struct object_entry * obj )
566+ {
567+ return unpack_data (obj , NULL , NULL );
568+ }
569+
549570static int compare_delta_bases (const union delta_base * base1 ,
550571 const union delta_base * base2 ,
551572 enum object_type type1 ,
0 commit comments