| 3646 | #define IEOT_VERSION (1) |
| 3647 | |
| 3648 | static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset) |
| 3649 | { |
| 3650 | const char *index = NULL; |
| 3651 | uint32_t extsize, ext_version; |
| 3652 | struct index_entry_offset_table *ieot; |
| 3653 | int i, nr; |
| 3654 | |
| 3655 | /* find the IEOT extension */ |
| 3656 | if (!offset) |
| 3657 | return NULL; |
| 3658 | while (offset <= mmap_size - the_hash_algo->rawsz - 8) { |
| 3659 | extsize = get_be32(mmap + offset + 4); |
| 3660 | if (CACHE_EXT((mmap + offset)) == CACHE_EXT_INDEXENTRYOFFSETTABLE) { |
| 3661 | index = mmap + offset + 4 + 4; |
| 3662 | break; |
| 3663 | } |
| 3664 | offset += 8; |
| 3665 | offset += extsize; |
| 3666 | } |
| 3667 | if (!index) |
| 3668 | return NULL; |
| 3669 | |
| 3670 | /* validate the version is IEOT_VERSION */ |
| 3671 | ext_version = get_be32(index); |
| 3672 | if (ext_version != IEOT_VERSION) { |
| 3673 | error("invalid IEOT version %d", ext_version); |
| 3674 | return NULL; |
| 3675 | } |
| 3676 | index += sizeof(uint32_t); |
| 3677 | |
| 3678 | /* extension size - version bytes / bytes per entry */ |
| 3679 | nr = (extsize - sizeof(uint32_t)) / (sizeof(uint32_t) + sizeof(uint32_t)); |
| 3680 | if (!nr) { |
| 3681 | error("invalid number of IEOT entries %d", nr); |
| 3682 | return NULL; |
| 3683 | } |
| 3684 | ieot = xmalloc(sizeof(struct index_entry_offset_table) |
| 3685 | + (nr * sizeof(struct index_entry_offset))); |
| 3686 | ieot->nr = nr; |
| 3687 | for (i = 0; i < nr; i++) { |
| 3688 | ieot->entries[i].offset = get_be32(index); |
| 3689 | index += sizeof(uint32_t); |
| 3690 | ieot->entries[i].nr = get_be32(index); |
| 3691 | index += sizeof(uint32_t); |
| 3692 | } |
| 3693 | |
| 3694 | return ieot; |
| 3695 | } |
| 3696 | |
| 3697 | static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot) |
| 3698 | { |
no test coverage detected