* Parses the contents of the cache entry contained within the 'ondisk' buffer * into a new incore 'cache_entry'. * * Note that 'char *ondisk' may not be aligned to a 4-byte address interval in * index v4, so we cannot cast it to 'struct ondisk_cache_entry *' and access * its members. Instead, we use the byte offsets of members within the struct to * identify where 'get_be16()', 'get_be32()',
| 1779 | * into the corresponding incore 'cache_entry' members. |
| 1780 | */ |
| 1781 | static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool, |
| 1782 | unsigned int version, |
| 1783 | const char *ondisk, |
| 1784 | unsigned long *ent_size, |
| 1785 | const struct cache_entry *previous_ce) |
| 1786 | { |
| 1787 | struct cache_entry *ce; |
| 1788 | size_t len; |
| 1789 | const char *name; |
| 1790 | const unsigned hashsz = the_hash_algo->rawsz; |
| 1791 | const char *flagsp = ondisk + offsetof(struct ondisk_cache_entry, data) + hashsz; |
| 1792 | unsigned int flags; |
| 1793 | size_t copy_len = 0; |
| 1794 | /* |
| 1795 | * Adjacent cache entries tend to share the leading paths, so it makes |
| 1796 | * sense to only store the differences in later entries. In the v4 |
| 1797 | * on-disk format of the index, each on-disk cache entry stores the |
| 1798 | * number of bytes to be stripped from the end of the previous name, |
| 1799 | * and the bytes to append to the result, to come up with its name. |
| 1800 | */ |
| 1801 | int expand_name_field = version == 4; |
| 1802 | |
| 1803 | /* On-disk flags are just 16 bits */ |
| 1804 | flags = get_be16(flagsp); |
| 1805 | len = flags & CE_NAMEMASK; |
| 1806 | |
| 1807 | if (flags & CE_EXTENDED) { |
| 1808 | int extended_flags; |
| 1809 | extended_flags = get_be16(flagsp + sizeof(uint16_t)) << 16; |
| 1810 | /* We do not yet understand any bit out of CE_EXTENDED_FLAGS */ |
| 1811 | if (extended_flags & ~CE_EXTENDED_FLAGS) |
| 1812 | die(_("unknown index entry format 0x%08x"), extended_flags); |
| 1813 | flags |= extended_flags; |
| 1814 | name = (const char *)(flagsp + 2 * sizeof(uint16_t)); |
| 1815 | } |
| 1816 | else |
| 1817 | name = (const char *)(flagsp + sizeof(uint16_t)); |
| 1818 | |
| 1819 | if (expand_name_field) { |
| 1820 | const unsigned char *cp = (const unsigned char *)name; |
| 1821 | uint64_t strip_len, previous_len; |
| 1822 | |
| 1823 | /* If we're at the beginning of a block, ignore the previous name */ |
| 1824 | strip_len = decode_varint(&cp); |
| 1825 | if (previous_ce) { |
| 1826 | previous_len = previous_ce->ce_namelen; |
| 1827 | if (previous_len < strip_len) |
| 1828 | die(_("malformed name field in the index, near path '%s'"), |
| 1829 | previous_ce->name); |
| 1830 | copy_len = previous_len - strip_len; |
| 1831 | } |
| 1832 | name = (const char *)cp; |
| 1833 | } |
| 1834 | |
| 1835 | if (len == CE_NAMEMASK) { |
| 1836 | len = strlen(name); |
| 1837 | if (expand_name_field) |
| 1838 | len += copy_len; |
no test coverage detected