| 3864 | } |
| 3865 | |
| 3866 | struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz) |
| 3867 | { |
| 3868 | struct untracked_cache *uc; |
| 3869 | struct read_data rd; |
| 3870 | const unsigned char *next = data, *end = (const unsigned char *)data + sz; |
| 3871 | const char *ident; |
| 3872 | uint64_t ident_len; |
| 3873 | uint64_t varint_len; |
| 3874 | ssize_t len; |
| 3875 | const char *exclude_per_dir; |
| 3876 | const unsigned hashsz = the_hash_algo->rawsz; |
| 3877 | const unsigned offset = sizeof(struct ondisk_untracked_cache); |
| 3878 | const unsigned exclude_per_dir_offset = offset + 2 * hashsz; |
| 3879 | |
| 3880 | if (sz <= 1 || end[-1] != '\0') |
| 3881 | return NULL; |
| 3882 | end--; |
| 3883 | |
| 3884 | ident_len = decode_varint(&next); |
| 3885 | if (next + ident_len > end) |
| 3886 | return NULL; |
| 3887 | ident = (const char *)next; |
| 3888 | next += ident_len; |
| 3889 | |
| 3890 | if (next + exclude_per_dir_offset + 1 > end) |
| 3891 | return NULL; |
| 3892 | |
| 3893 | CALLOC_ARRAY(uc, 1); |
| 3894 | strbuf_init(&uc->ident, ident_len); |
| 3895 | strbuf_add(&uc->ident, ident, ident_len); |
| 3896 | load_oid_stat(&uc->ss_info_exclude, |
| 3897 | next + ouc_offset(info_exclude_stat), |
| 3898 | next + offset); |
| 3899 | load_oid_stat(&uc->ss_excludes_file, |
| 3900 | next + ouc_offset(excludes_file_stat), |
| 3901 | next + offset + hashsz); |
| 3902 | uc->dir_flags = get_be32(next + ouc_offset(dir_flags)); |
| 3903 | exclude_per_dir = (const char *)next + exclude_per_dir_offset; |
| 3904 | uc->exclude_per_dir = uc->exclude_per_dir_to_free = xstrdup(exclude_per_dir); |
| 3905 | /* NUL after exclude_per_dir is covered by sizeof(*ouc) */ |
| 3906 | next += exclude_per_dir_offset + strlen(exclude_per_dir) + 1; |
| 3907 | if (next >= end) |
| 3908 | goto done2; |
| 3909 | |
| 3910 | varint_len = decode_varint(&next); |
| 3911 | if (next > end || varint_len == 0) |
| 3912 | goto done2; |
| 3913 | |
| 3914 | rd.valid = ewah_new(); |
| 3915 | rd.check_only = ewah_new(); |
| 3916 | rd.sha1_valid = ewah_new(); |
| 3917 | rd.data = next; |
| 3918 | rd.end = end; |
| 3919 | rd.index = 0; |
| 3920 | ALLOC_ARRAY(rd.ucd, varint_len); |
| 3921 | |
| 3922 | if (read_one_dir(&uc->root, &rd) || rd.index != varint_len) |
| 3923 | goto done; |
no test coverage detected