@@ -277,6 +277,8 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r,
277
277
278
278
static int verify_commit_graph_lite (struct commit_graph * g )
279
279
{
280
+ int i ;
281
+
280
282
/*
281
283
* Basic validation shared between parse_commit_graph()
282
284
* which'll be called every time the graph is used, and the
@@ -302,6 +304,30 @@ static int verify_commit_graph_lite(struct commit_graph *g)
302
304
return 1 ;
303
305
}
304
306
307
+ for (i = 0 ; i < 255 ; i ++ ) {
308
+ uint32_t oid_fanout1 = ntohl (g -> chunk_oid_fanout [i ]);
309
+ uint32_t oid_fanout2 = ntohl (g -> chunk_oid_fanout [i + 1 ]);
310
+
311
+ if (oid_fanout1 > oid_fanout2 ) {
312
+ error ("commit-graph fanout values out of order" );
313
+ return 1 ;
314
+ }
315
+ }
316
+ if (ntohl (g -> chunk_oid_fanout [255 ]) != g -> num_commits ) {
317
+ error ("commit-graph oid table and fanout disagree on size" );
318
+ return 1 ;
319
+ }
320
+
321
+ return 0 ;
322
+ }
323
+
324
+ static int graph_read_oid_fanout (const unsigned char * chunk_start ,
325
+ size_t chunk_size , void * data )
326
+ {
327
+ struct commit_graph * g = data ;
328
+ if (chunk_size != 256 * sizeof (uint32_t ))
329
+ return error ("commit-graph oid fanout chunk is wrong size" );
330
+ g -> chunk_oid_fanout = (const uint32_t * )chunk_start ;
305
331
return 0 ;
306
332
}
307
333
@@ -314,12 +340,54 @@ static int graph_read_oid_lookup(const unsigned char *chunk_start,
314
340
return 0 ;
315
341
}
316
342
343
+ static int graph_read_commit_data (const unsigned char * chunk_start ,
344
+ size_t chunk_size , void * data )
345
+ {
346
+ struct commit_graph * g = data ;
347
+ if (chunk_size != g -> num_commits * GRAPH_DATA_WIDTH )
348
+ return error ("commit-graph commit data chunk is wrong size" );
349
+ g -> chunk_commit_data = chunk_start ;
350
+ return 0 ;
351
+ }
352
+
353
+ static int graph_read_generation_data (const unsigned char * chunk_start ,
354
+ size_t chunk_size , void * data )
355
+ {
356
+ struct commit_graph * g = data ;
357
+ if (chunk_size != g -> num_commits * sizeof (uint32_t ))
358
+ return error ("commit-graph generations chunk is wrong size" );
359
+ g -> chunk_generation_data = chunk_start ;
360
+ return 0 ;
361
+ }
362
+
363
+ static int graph_read_bloom_index (const unsigned char * chunk_start ,
364
+ size_t chunk_size , void * data )
365
+ {
366
+ struct commit_graph * g = data ;
367
+ if (chunk_size != g -> num_commits * 4 ) {
368
+ warning ("commit-graph changed-path index chunk is too small" );
369
+ return -1 ;
370
+ }
371
+ g -> chunk_bloom_indexes = chunk_start ;
372
+ return 0 ;
373
+ }
374
+
317
375
static int graph_read_bloom_data (const unsigned char * chunk_start ,
318
376
size_t chunk_size , void * data )
319
377
{
320
378
struct commit_graph * g = data ;
321
379
uint32_t hash_version ;
380
+
381
+ if (chunk_size < BLOOMDATA_CHUNK_HEADER_SIZE ) {
382
+ warning ("ignoring too-small changed-path chunk"
383
+ " (%" PRIuMAX " < %" PRIuMAX ") in commit-graph file" ,
384
+ (uintmax_t )chunk_size ,
385
+ (uintmax_t )BLOOMDATA_CHUNK_HEADER_SIZE );
386
+ return -1 ;
387
+ }
388
+
322
389
g -> chunk_bloom_data = chunk_start ;
390
+ g -> chunk_bloom_data_size = chunk_size ;
323
391
hash_version = get_be32 (chunk_start );
324
392
325
393
if (hash_version != 1 )
@@ -391,29 +459,31 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s,
391
459
cf = init_chunkfile (NULL );
392
460
393
461
if (read_table_of_contents (cf , graph -> data , graph_size ,
394
- GRAPH_HEADER_SIZE , graph -> num_chunks ))
462
+ GRAPH_HEADER_SIZE , graph -> num_chunks , 1 ))
395
463
goto free_and_return ;
396
464
397
- pair_chunk (cf , GRAPH_CHUNKID_OIDFANOUT ,
398
- (const unsigned char * * )& graph -> chunk_oid_fanout );
465
+ read_chunk (cf , GRAPH_CHUNKID_OIDFANOUT , graph_read_oid_fanout , graph );
399
466
read_chunk (cf , GRAPH_CHUNKID_OIDLOOKUP , graph_read_oid_lookup , graph );
400
- pair_chunk (cf , GRAPH_CHUNKID_DATA , & graph -> chunk_commit_data );
401
- pair_chunk (cf , GRAPH_CHUNKID_EXTRAEDGES , & graph -> chunk_extra_edges );
402
- pair_chunk (cf , GRAPH_CHUNKID_BASE , & graph -> chunk_base_graphs );
467
+ read_chunk (cf , GRAPH_CHUNKID_DATA , graph_read_commit_data , graph );
468
+ pair_chunk (cf , GRAPH_CHUNKID_EXTRAEDGES , & graph -> chunk_extra_edges ,
469
+ & graph -> chunk_extra_edges_size );
470
+ pair_chunk (cf , GRAPH_CHUNKID_BASE , & graph -> chunk_base_graphs ,
471
+ & graph -> chunk_base_graphs_size );
403
472
404
473
if (s -> commit_graph_generation_version >= 2 ) {
405
- pair_chunk (cf , GRAPH_CHUNKID_GENERATION_DATA ,
406
- & graph -> chunk_generation_data );
474
+ read_chunk (cf , GRAPH_CHUNKID_GENERATION_DATA ,
475
+ graph_read_generation_data , graph );
407
476
pair_chunk (cf , GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW ,
408
- & graph -> chunk_generation_data_overflow );
477
+ & graph -> chunk_generation_data_overflow ,
478
+ & graph -> chunk_generation_data_overflow_size );
409
479
410
480
if (graph -> chunk_generation_data )
411
481
graph -> read_generation_data = 1 ;
412
482
}
413
483
414
484
if (s -> commit_graph_read_changed_paths ) {
415
- pair_chunk (cf , GRAPH_CHUNKID_BLOOMINDEXES ,
416
- & graph -> chunk_bloom_indexes );
485
+ read_chunk (cf , GRAPH_CHUNKID_BLOOMINDEXES ,
486
+ graph_read_bloom_index , graph );
417
487
read_chunk (cf , GRAPH_CHUNKID_BLOOMDATA ,
418
488
graph_read_bloom_data , graph );
419
489
}
@@ -510,6 +580,11 @@ static int add_graph_to_chain(struct commit_graph *g,
510
580
return 0 ;
511
581
}
512
582
583
+ if (g -> chunk_base_graphs_size / g -> hash_len < n ) {
584
+ warning (_ ("commit-graph base graphs chunk is too small" ));
585
+ return 0 ;
586
+ }
587
+
513
588
while (n ) {
514
589
n -- ;
515
590
@@ -837,7 +912,10 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g,
837
912
die (_ ("commit-graph requires overflow generation data but has none" ));
838
913
839
914
offset_pos = offset ^ CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW ;
840
- graph_data -> generation = item -> date + get_be64 (g -> chunk_generation_data_overflow + st_mult (8 , offset_pos ));
915
+ if (g -> chunk_generation_data_overflow_size / sizeof (uint64_t ) <= offset_pos )
916
+ die (_ ("commit-graph overflow generation data is too small" ));
917
+ graph_data -> generation = item -> date +
918
+ get_be64 (g -> chunk_generation_data_overflow + sizeof (uint64_t ) * offset_pos );
841
919
} else
842
920
graph_data -> generation = item -> date + offset ;
843
921
} else
@@ -857,7 +935,7 @@ static int fill_commit_in_graph(struct repository *r,
857
935
struct commit_graph * g , uint32_t pos )
858
936
{
859
937
uint32_t edge_value ;
860
- uint32_t * parent_data_ptr ;
938
+ uint32_t parent_data_pos ;
861
939
struct commit_list * * pptr ;
862
940
const unsigned char * commit_data ;
863
941
uint32_t lex_index ;
@@ -889,14 +967,21 @@ static int fill_commit_in_graph(struct repository *r,
889
967
return 1 ;
890
968
}
891
969
892
- parent_data_ptr = (uint32_t * )(g -> chunk_extra_edges +
893
- st_mult (4 , edge_value & GRAPH_EDGE_LAST_MASK ));
970
+ parent_data_pos = edge_value & GRAPH_EDGE_LAST_MASK ;
894
971
do {
895
- edge_value = get_be32 (parent_data_ptr );
972
+ if (g -> chunk_extra_edges_size / sizeof (uint32_t ) <= parent_data_pos ) {
973
+ error ("commit-graph extra-edges pointer out of bounds" );
974
+ free_commit_list (item -> parents );
975
+ item -> parents = NULL ;
976
+ item -> object .parsed = 0 ;
977
+ return 0 ;
978
+ }
979
+ edge_value = get_be32 (g -> chunk_extra_edges +
980
+ sizeof (uint32_t ) * parent_data_pos );
896
981
pptr = insert_parent_or_die (r , g ,
897
982
edge_value & GRAPH_EDGE_LAST_MASK ,
898
983
pptr );
899
- parent_data_ptr ++ ;
984
+ parent_data_pos ++ ;
900
985
} while (!(edge_value & GRAPH_LAST_EDGE ));
901
986
902
987
return 1 ;
0 commit comments