Skip to content

Commit cb6ba49

Browse files
brandb97gitster
authored andcommitted
pack-bitmap: add load corrupt bitmap test
This patch add test_bitmap_list_commits_offset() in patch-bitmap.c, a new test helper command `test-tool bitmap list-commits-offset`, and a `load corrupt bitmap` test case in t5310. The `load corrupt bitmap` test case intentionally corrupt the "xor_offset" field of the first entry. And the newly added helper can help to find position of "xor_offset" in bitmap file. Signed-off-by: Lidong Yan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ee6319e commit cb6ba49

File tree

4 files changed

+103
-6
lines changed

4 files changed

+103
-6
lines changed

pack-bitmap.c

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ struct stored_bitmap {
3434
int flags;
3535
};
3636

37+
struct stored_bitmap_tag_pos {
38+
struct stored_bitmap stored;
39+
size_t map_pos;
40+
};
41+
3742
/*
3843
* The active bitmap index for a repository. By design, repositories only have
3944
* a single bitmap index available (the index for the biggest packfile in
@@ -148,6 +153,7 @@ static int existing_bitmaps_hits_nr;
148153
static int existing_bitmaps_misses_nr;
149154
static int roots_with_bitmaps_nr;
150155
static int roots_without_bitmaps_nr;
156+
static int tag_pos_on_bitmap;
151157

152158
static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
153159
{
@@ -314,13 +320,18 @@ static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
314320
struct ewah_bitmap *root,
315321
const struct object_id *oid,
316322
struct stored_bitmap *xor_with,
317-
int flags)
323+
int flags, size_t map_pos)
318324
{
319325
struct stored_bitmap *stored;
326+
struct stored_bitmap_tag_pos *tagged;
320327
khiter_t hash_pos;
321328
int ret;
322329

323-
stored = xmalloc(sizeof(struct stored_bitmap));
330+
tagged = xmalloc(tag_pos_on_bitmap ? sizeof(struct stored_bitmap_tag_pos) :
331+
sizeof(struct stored_bitmap));
332+
stored = &tagged->stored;
333+
if (tag_pos_on_bitmap)
334+
tagged->map_pos = map_pos;
324335
stored->root = root;
325336
stored->xor = xor_with;
326337
stored->flags = flags;
@@ -376,10 +387,12 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
376387
struct stored_bitmap *xor_bitmap = NULL;
377388
uint32_t commit_idx_pos;
378389
struct object_id oid;
390+
size_t entry_map_pos;
379391

380392
if (index->map_size - index->map_pos < 6)
381393
return error(_("corrupt ewah bitmap: truncated header for entry %d"), i);
382394

395+
entry_map_pos = index->map_pos;
383396
commit_idx_pos = read_be32(index->map, &index->map_pos);
384397
xor_offset = read_u8(index->map, &index->map_pos);
385398
flags = read_u8(index->map, &index->map_pos);
@@ -402,8 +415,9 @@ static int load_bitmap_entries_v1(struct bitmap_index *index)
402415
if (!bitmap)
403416
return -1;
404417

405-
recent_bitmaps[i % MAX_XOR_OFFSET] = store_bitmap(
406-
index, bitmap, &oid, xor_bitmap, flags);
418+
recent_bitmaps[i % MAX_XOR_OFFSET] =
419+
store_bitmap(index, bitmap, &oid, xor_bitmap, flags,
420+
entry_map_pos);
407421
}
408422

409423
return 0;
@@ -869,6 +883,7 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
869883
int xor_flags;
870884
khiter_t hash_pos;
871885
struct bitmap_lookup_table_xor_item *xor_item;
886+
size_t entry_map_pos;
872887

873888
if (is_corrupt)
874889
return NULL;
@@ -928,14 +943,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
928943
goto corrupt;
929944
}
930945

946+
entry_map_pos = bitmap_git->map_pos;
931947
bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
932948
xor_flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
933949
bitmap = read_bitmap_1(bitmap_git);
934950

935951
if (!bitmap)
936952
goto corrupt;
937953

938-
xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid, xor_bitmap, xor_flags);
954+
xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid,
955+
xor_bitmap, xor_flags, entry_map_pos);
939956
xor_items_nr--;
940957
}
941958

@@ -969,14 +986,16 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
969986
* Instead, we can skip ahead and immediately read the flags and
970987
* ewah bitmap.
971988
*/
989+
entry_map_pos = bitmap_git->map_pos;
972990
bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
973991
flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
974992
bitmap = read_bitmap_1(bitmap_git);
975993

976994
if (!bitmap)
977995
goto corrupt;
978996

979-
return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags);
997+
return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags,
998+
entry_map_pos);
980999

9811000
corrupt:
9821001
free(xor_items);
@@ -2856,6 +2875,48 @@ int test_bitmap_commits(struct repository *r)
28562875
return 0;
28572876
}
28582877

2878+
int test_bitmap_commits_offset(struct repository *r)
2879+
{
2880+
struct object_id oid;
2881+
struct stored_bitmap_tag_pos *tagged;
2882+
struct bitmap_index *bitmap_git;
2883+
size_t commit_idx_pos_map_pos, xor_offset_map_pos, flag_map_pos,
2884+
ewah_bitmap_map_pos;
2885+
2886+
tag_pos_on_bitmap = 1;
2887+
bitmap_git = prepare_bitmap_git(r);
2888+
if (!bitmap_git)
2889+
die(_("failed to load bitmap indexes"));
2890+
2891+
/*
2892+
* As this function is only used to print bitmap selected
2893+
* commits, we don't have to read the commit table.
2894+
*/
2895+
if (bitmap_git->table_lookup) {
2896+
if (load_bitmap_entries_v1(bitmap_git) < 0)
2897+
die(_("failed to load bitmap indexes"));
2898+
}
2899+
2900+
kh_foreach (bitmap_git->bitmaps, oid, tagged, {
2901+
commit_idx_pos_map_pos = tagged->map_pos;
2902+
xor_offset_map_pos = tagged->map_pos + sizeof(uint32_t);
2903+
flag_map_pos = xor_offset_map_pos + sizeof(uint8_t);
2904+
ewah_bitmap_map_pos = flag_map_pos + sizeof(uint8_t);
2905+
2906+
printf_ln("%s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
2907+
oid_to_hex(&oid),
2908+
(uintmax_t)commit_idx_pos_map_pos,
2909+
(uintmax_t)xor_offset_map_pos,
2910+
(uintmax_t)flag_map_pos,
2911+
(uintmax_t)ewah_bitmap_map_pos);
2912+
})
2913+
;
2914+
2915+
free_bitmap_index(bitmap_git);
2916+
2917+
return 0;
2918+
}
2919+
28592920
int test_bitmap_hashes(struct repository *r)
28602921
{
28612922
struct bitmap_index *bitmap_git = prepare_bitmap_git(r);

pack-bitmap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ void traverse_bitmap_commit_list(struct bitmap_index *,
8181
show_reachable_fn show_reachable);
8282
void test_bitmap_walk(struct rev_info *revs);
8383
int test_bitmap_commits(struct repository *r);
84+
int test_bitmap_commits_offset(struct repository *r);
8485
int test_bitmap_hashes(struct repository *r);
8586
int test_bitmap_pseudo_merges(struct repository *r);
8687
int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n);

t/helper/test-bitmap.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ static int bitmap_list_commits(void)
1010
return test_bitmap_commits(the_repository);
1111
}
1212

13+
static int bitmap_list_commits_offset(void)
14+
{
15+
return test_bitmap_commits_offset(the_repository);
16+
}
17+
1318
static int bitmap_dump_hashes(void)
1419
{
1520
return test_bitmap_hashes(the_repository);
@@ -36,6 +41,8 @@ int cmd__bitmap(int argc, const char **argv)
3641

3742
if (argc == 2 && !strcmp(argv[1], "list-commits"))
3843
return bitmap_list_commits();
44+
if (argc == 2 && !strcmp(argv[1], "list-commits-offset"))
45+
return bitmap_list_commits_offset();
3946
if (argc == 2 && !strcmp(argv[1], "dump-hashes"))
4047
return bitmap_dump_hashes();
4148
if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges"))
@@ -46,6 +53,7 @@ int cmd__bitmap(int argc, const char **argv)
4653
return bitmap_dump_pseudo_merge_objects(atoi(argv[2]));
4754

4855
usage("\ttest-tool bitmap list-commits\n"
56+
"\ttest-tool bitmap list-commits-offset\n"
4957
"\ttest-tool bitmap dump-hashes\n"
5058
"\ttest-tool bitmap dump-pseudo-merges\n"
5159
"\ttest-tool bitmap dump-pseudo-merge-commits <n>\n"

t/t5310-pack-bitmaps.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,33 @@ test_bitmap_cases () {
486486
grep "ignoring extra bitmap" trace2.txt
487487
)
488488
'
489+
490+
test_expect_success 'load corrupt bitmap' '
491+
rm -fr repo &&
492+
git init repo &&
493+
test_when_finished "rm -fr repo" &&
494+
(
495+
cd repo &&
496+
git config pack.writeBitmapLookupTable '"$writeLookupTable"' &&
497+
498+
test_commit base &&
499+
500+
git repack -adb &&
501+
bitmap="$(ls .git/objects/pack/pack-*.bitmap)" &&
502+
chmod +w $bitmap &&
503+
504+
read oid commit_off xor_off flag_off ewah_off <<-EOF &&
505+
$(test-tool bitmap list-commits-offset | head -n 1)
506+
EOF
507+
printf '\161' |
508+
dd of=$bitmap count=1 bs=1 conv=notrunc seek=$xor_off &&
509+
510+
511+
git rev-list --count HEAD > expect &&
512+
git rev-list --use-bitmap-index --count HEAD > actual &&
513+
test_cmp expect actual
514+
)
515+
'
489516
}
490517

491518
test_bitmap_cases

0 commit comments

Comments
 (0)