blob: b79099710441262305290bd45a39e29359924008 [file] [log] [blame]
/* Reduced from git-2.39.0's pack-revindex.c */
/* { dg-additional-options "-fno-exceptions" } */
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;
}