| 243 | } |
| 244 | |
| 245 | static int load_bitmap_header(struct bitmap_index *index) |
| 246 | { |
| 247 | struct bitmap_disk_header *header = (void *)index->map; |
| 248 | const struct git_hash_algo *hash_algo = bitmap_repo(index)->hash_algo; |
| 249 | |
| 250 | size_t header_size = sizeof(*header) - GIT_MAX_RAWSZ + hash_algo->rawsz; |
| 251 | |
| 252 | if (index->map_size < header_size + hash_algo->rawsz) |
| 253 | return error(_("corrupted bitmap index (too small)")); |
| 254 | |
| 255 | if (memcmp(header->magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)) != 0) |
| 256 | return error(_("corrupted bitmap index file (wrong header)")); |
| 257 | |
| 258 | index->version = ntohs(header->version); |
| 259 | if (index->version != 1) |
| 260 | return error(_("unsupported version '%d' for bitmap index file"), index->version); |
| 261 | |
| 262 | /* Parse known bitmap format options */ |
| 263 | { |
| 264 | uint32_t flags = ntohs(header->options); |
| 265 | size_t cache_size = st_mult(bitmap_num_objects(index), sizeof(uint32_t)); |
| 266 | unsigned char *index_end = index->map + index->map_size - hash_algo->rawsz; |
| 267 | |
| 268 | if ((flags & BITMAP_OPT_FULL_DAG) == 0) |
| 269 | BUG("unsupported options for bitmap index file " |
| 270 | "(Git requires BITMAP_OPT_FULL_DAG)"); |
| 271 | |
| 272 | if (flags & BITMAP_OPT_HASH_CACHE) { |
| 273 | if (cache_size > index_end - index->map - header_size) |
| 274 | return error(_("corrupted bitmap index file (too short to fit hash cache)")); |
| 275 | index->hashes = (void *)(index_end - cache_size); |
| 276 | index_end -= cache_size; |
| 277 | } |
| 278 | |
| 279 | if (flags & BITMAP_OPT_LOOKUP_TABLE) { |
| 280 | size_t table_size = st_mult(ntohl(header->entry_count), |
| 281 | BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH); |
| 282 | if (table_size > index_end - index->map - header_size) |
| 283 | return error(_("corrupted bitmap index file (too short to fit lookup table)")); |
| 284 | if (git_env_bool("GIT_TEST_READ_COMMIT_TABLE", 1)) |
| 285 | index->table_lookup = (void *)(index_end - table_size); |
| 286 | index_end -= table_size; |
| 287 | } |
| 288 | |
| 289 | if (flags & BITMAP_OPT_PSEUDO_MERGES) { |
| 290 | unsigned char *pseudo_merge_ofs; |
| 291 | size_t table_size; |
| 292 | uint32_t i; |
| 293 | |
| 294 | if (sizeof(table_size) > index_end - index->map - header_size) |
| 295 | return error(_("corrupted bitmap index file (too short to fit pseudo-merge table header)")); |
| 296 | |
| 297 | table_size = get_be64(index_end - 8); |
| 298 | if (table_size > index_end - index->map - header_size) |
| 299 | return error(_("corrupted bitmap index file (too short to fit pseudo-merge table)")); |
| 300 | |
| 301 | if (git_env_bool("GIT_TEST_USE_PSEUDO_MERGES", 1)) { |
| 302 | const unsigned char *ext = (index_end - table_size); |
no test coverage detected