1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/* Reduced from git-2.39.0's pack-revindex.c */
typedef unsigned int __uint32_t;
typedef unsigned long int __uintmax_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef __SIZE_TYPE__ size_t;
typedef __off64_t off_t;
typedef __uint32_t uint32_t;
typedef __uintmax_t uintmax_t;
struct stat {
/* [...snip...] */
__off_t st_size;
/* [...snip...] */
};
extern int close(int __fd);
extern int fstat(int __fd, struct stat *__buf)
__attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2)));
extern uint32_t default_swab32(uint32_t val);
extern uint32_t git_bswap32(uint32_t x);
__attribute__((__noreturn__)) void die(const char *err, ...)
__attribute__((format(printf, 1, 2)));
int error(const char *err, ...) __attribute__((format(printf, 1, 2)));
int error_errno(const char *err, ...) __attribute__((format(printf, 1, 2)));
static inline int const_error(void) { return -1; }
extern int munmap(void *__addr, size_t __len)
__attribute__((__nothrow__, __leaf__));
extern size_t st_mult(size_t a, size_t b);
extern void *xmmap(void *start, size_t length, int prot, int flags, int fd,
off_t offset);
extern size_t xsize_t(off_t len);
extern char *gettext(const char *__msgid) __attribute__((__nothrow__, __leaf__))
__attribute__((__format_arg__(1)));
static inline __attribute__((format_arg(1))) const char *_(const char *msgid) {
if (!*msgid)
return "";
return gettext(msgid);
}
struct repository {
/* [...snip...] */
const struct git_hash_algo *hash_algo;
/* [...snip...] */
};
extern struct repository *the_repository;
struct git_hash_algo {
/* [...snip...] */
size_t rawsz;
/* [...snip...] */
};
int git_open_cloexec(const char *name, int flags);
struct revindex_header {
uint32_t signature;
uint32_t version;
uint32_t hash_id;
};
int load_revindex_from_disk(char *revindex_name, uint32_t num_objects,
const uint32_t **data_p, size_t *len_p) {
int fd, ret = 0;
struct stat st;
void *data = ((void *)0);
size_t revindex_size;
struct revindex_header *hdr;
fd = git_open_cloexec(revindex_name, 00);
if (fd < 0) {
ret = -1;
goto cleanup;
}
if (fstat(fd, &st)) {
ret = (error_errno(_("failed to read %s"), revindex_name), const_error());
goto cleanup;
}
revindex_size = xsize_t(st.st_size);
if (revindex_size < ((12) + (2 * the_repository->hash_algo->rawsz))) {
ret = (error(_("reverse-index file %s is too small"), revindex_name),
const_error());
goto cleanup;
}
if (revindex_size - ((12) + (2 * the_repository->hash_algo->rawsz)) !=
st_mult(sizeof(uint32_t), num_objects)) {
ret = (error(_("reverse-index file %s is corrupt"), revindex_name),
const_error());
goto cleanup;
}
data = xmmap(((void *)0), revindex_size, 0x1, 0x02, fd, 0);
hdr = (struct revindex_header *) data;
if (git_bswap32(hdr->signature) != 0x52494458) {
ret =
(error(_("reverse-index file %s has unknown signature"), revindex_name),
const_error());
goto cleanup;
}
if (git_bswap32(hdr->version) != 1) {
ret = (error(_("reverse-index file %s has unsupported version %"
"u"),
revindex_name, git_bswap32(hdr->version)),
const_error());
goto cleanup;
}
if (!(git_bswap32(hdr->hash_id) == 1 || git_bswap32(hdr->hash_id) == 2)) {
ret = (error(_("reverse-index file %s has unsupported hash id %"
"u"),
revindex_name, git_bswap32(hdr->hash_id)),
const_error());
goto cleanup;
}
cleanup:
if (ret) {
if (data) /* { dg-bogus "check of 'data' for NULL after already dereferencing it" } */
munmap(data, revindex_size);
} else {
*len_p = revindex_size;
*data_p = (const uint32_t *)data;
}
if (fd >= 0)
close(fd);
return ret;
}
|