@@ -65,6 +65,7 @@ static unsigned char pack_file_sha1[20];
6565static int progress = 1 ;
6666static volatile sig_atomic_t progress_update ;
6767static int window = 10 ;
68+ static int pack_to_stdout ;
6869
6970/*
7071 * The object names in objects array are hashed with this hashtable,
@@ -242,6 +243,82 @@ static int encode_header(enum object_type type, unsigned long size, unsigned cha
242243 return n ;
243244}
244245
246+ static int check_inflate (unsigned char * data , unsigned long len , unsigned long expect )
247+ {
248+ z_stream stream ;
249+ unsigned char fakebuf [4096 ];
250+ int st ;
251+
252+ memset (& stream , 0 , sizeof (stream ));
253+ stream .next_in = data ;
254+ stream .avail_in = len ;
255+ stream .next_out = fakebuf ;
256+ stream .avail_out = sizeof (fakebuf );
257+ inflateInit (& stream );
258+
259+ while (1 ) {
260+ st = inflate (& stream , Z_FINISH );
261+ if (st == Z_STREAM_END || st == Z_OK ) {
262+ st = (stream .total_out == expect &&
263+ stream .total_in == len ) ? 0 : -1 ;
264+ break ;
265+ }
266+ if (st != Z_BUF_ERROR ) {
267+ st = -1 ;
268+ break ;
269+ }
270+ stream .next_out = fakebuf ;
271+ stream .avail_out = sizeof (fakebuf );
272+ }
273+ inflateEnd (& stream );
274+ return st ;
275+ }
276+
277+ /*
278+ * we are going to reuse the existing pack entry data. make
279+ * sure it is not corrupt.
280+ */
281+ static int revalidate_pack_entry (struct object_entry * entry , unsigned char * data , unsigned long len )
282+ {
283+ enum object_type type ;
284+ unsigned long size , used ;
285+
286+ if (pack_to_stdout )
287+ return 0 ;
288+
289+ /* the caller has already called use_packed_git() for us,
290+ * so it is safe to access the pack data from mmapped location.
291+ * make sure the entry inflates correctly.
292+ */
293+ used = unpack_object_header_gently (data , len , & type , & size );
294+ if (!used )
295+ return -1 ;
296+ if (type == OBJ_DELTA )
297+ used += 20 ; /* skip base object name */
298+ data += used ;
299+ len -= used ;
300+ return check_inflate (data , len , entry -> size );
301+ }
302+
303+ static int revalidate_loose_object (struct object_entry * entry ,
304+ unsigned char * map ,
305+ unsigned long mapsize )
306+ {
307+ /* we already know this is a loose object with new type header. */
308+ enum object_type type ;
309+ unsigned long size , used ;
310+
311+ if (pack_to_stdout )
312+ return 0 ;
313+
314+ used = unpack_object_header_gently (map , mapsize , & type , & size );
315+ if (!used )
316+ return -1 ;
317+ map += used ;
318+ mapsize -= used ;
319+ return check_inflate (map , mapsize , size );
320+ }
321+
245322static unsigned long write_object (struct sha1file * f ,
246323 struct object_entry * entry )
247324{
@@ -276,6 +353,9 @@ static unsigned long write_object(struct sha1file *f,
276353 map = map_sha1_file (entry -> sha1 , & mapsize );
277354 if (map && !legacy_loose_object (map )) {
278355 /* We can copy straight into the pack file */
356+ if (revalidate_loose_object (entry , map , mapsize ))
357+ die ("corrupt loose object %s" ,
358+ sha1_to_hex (entry -> sha1 ));
279359 sha1write (f , map , mapsize );
280360 munmap (map , mapsize );
281361 written ++ ;
@@ -286,7 +366,7 @@ static unsigned long write_object(struct sha1file *f,
286366 munmap (map , mapsize );
287367 }
288368
289- if (! to_reuse ) {
369+ if (!to_reuse ) {
290370 buf = read_sha1_file (entry -> sha1 , type , & size );
291371 if (!buf )
292372 die ("unable to read %s" , sha1_to_hex (entry -> sha1 ));
@@ -319,6 +399,9 @@ static unsigned long write_object(struct sha1file *f,
319399
320400 datalen = find_packed_object_size (p , entry -> in_pack_offset );
321401 buf = (char * ) p -> pack_base + entry -> in_pack_offset ;
402+
403+ if (revalidate_pack_entry (entry , buf , datalen ))
404+ die ("corrupt delta in pack %s" , sha1_to_hex (entry -> sha1 ));
322405 sha1write (f , buf , datalen );
323406 unuse_packed_git (p );
324407 hdrlen = 0 ; /* not really */
@@ -1163,7 +1246,7 @@ static void prepare_pack(int window, int depth)
11631246 find_deltas (sorted_by_type , window + 1 , depth );
11641247}
11651248
1166- static int reuse_cached_pack (unsigned char * sha1 , int pack_to_stdout )
1249+ static int reuse_cached_pack (unsigned char * sha1 )
11671250{
11681251 static const char cache [] = "pack-cache/pack-%s.%s" ;
11691252 char * cached_pack , * cached_idx ;
@@ -1247,7 +1330,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
12471330{
12481331 SHA_CTX ctx ;
12491332 char line [40 + 1 + PATH_MAX + 2 ];
1250- int depth = 10 , pack_to_stdout = 0 ;
1333+ int depth = 10 ;
12511334 struct object_entry * * list ;
12521335 int num_preferred_base = 0 ;
12531336 int i ;
@@ -1367,7 +1450,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
13671450 if (progress && (nr_objects != nr_result ))
13681451 fprintf (stderr , "Result has %d objects.\n" , nr_result );
13691452
1370- if (reuse_cached_pack (object_list_sha1 , pack_to_stdout ))
1453+ if (reuse_cached_pack (object_list_sha1 ))
13711454 ;
13721455 else {
13731456 if (nr_result )
0 commit comments