commit - 70015d7a0e09198dfe1d24d340818d8769ff6ab8
commit + 5e6be23258e2648c6ad1bf3b1d5617e827ac3ab6
blob - 7e7c69769bca88c55404098a3ff10d7603f937df
blob + 654dfa86d4de464fcdc3b68b5b8469f50f476a4c
--- lib/got_lib_pack.h
+++ lib/got_lib_pack.h
int fd;
uint8_t *map;
size_t len;
+ size_t nlargeobj;
struct got_packidx_v2_hdr hdr; /* convenient pointers into map */
};
blob - b6f49c5941537ece4825344a137f3cbe7ac37e24
blob + f4d09931a07992b989e1780e9a1409217e137e08
--- lib/pack.c
+++ lib/pack.c
uint8_t sha1[SHA1_DIGEST_LENGTH];
size_t nobj, len_fanout, len_ids, offset, remain;
ssize_t n;
+ int i;
SHA1Init(&ctx);
offset += nobj * sizeof(*h->offsets);
/* Large file offsets are contained only in files > 2GB. */
- if (p->len <= 0x80000000)
+ for (i = 0; i < nobj; i++) {
+ uint32_t o = betoh32(h->offsets[i]);
+ if (o & GOT_PACKIDX_OFFSET_VAL_IS_LARGE_IDX)
+ p->nlargeobj++;
+ }
+ if (p->nlargeobj == 0)
goto checksum;
- if (remain < nobj * sizeof(*h->large_offsets)) {
+ if (remain < p->nlargeobj * sizeof(*h->large_offsets)) {
err = got_error(GOT_ERR_BAD_PACKIDX);
goto done;
}
if (p->map)
h->large_offsets = (uint64_t *)((uint8_t*)(p->map + offset));
else {
- h->large_offsets = malloc(nobj * sizeof(*h->large_offsets));
+ h->large_offsets = malloc(p->nlargeobj *
+ sizeof(*h->large_offsets));
if (h->large_offsets == NULL) {
err = got_error_from_errno("malloc");
goto done;
}
n = read(p->fd, h->large_offsets,
- nobj * sizeof(*h->large_offsets));
+ p->nlargeobj * sizeof(*h->large_offsets));
if (n < 0)
err = got_error_from_errno("read");
- else if (n != nobj * sizeof(*h->large_offsets)) {
+ else if (n != p->nlargeobj * sizeof(*h->large_offsets)) {
err = got_error(GOT_ERR_BAD_PACKIDX);
goto done;
}
}
if (verify)
SHA1Update(&ctx, (uint8_t*)h->large_offsets,
- nobj * sizeof(*h->large_offsets));
- remain -= nobj * sizeof(*h->large_offsets);
- offset += nobj * sizeof(*h->large_offsets);
+ p->nlargeobj * sizeof(*h->large_offsets));
+ remain -= p->nlargeobj * sizeof(*h->large_offsets);
+ offset += p->nlargeobj * sizeof(*h->large_offsets);
checksum:
if (remain < sizeof(*h->trailer)) {
static off_t
get_object_offset(struct got_packidx *packidx, int idx)
{
- uint32_t totobj = betoh32(packidx->hdr.fanout_table[0xff]);
uint32_t offset = betoh32(packidx->hdr.offsets[idx]);
if (offset & GOT_PACKIDX_OFFSET_VAL_IS_LARGE_IDX) {
uint64_t loffset;
idx = offset & GOT_PACKIDX_OFFSET_VAL_MASK;
- if (idx < 0 || idx > totobj ||
+ if (idx < 0 || idx >= packidx->nlargeobj ||
packidx->hdr.large_offsets == NULL)
return -1;
loffset = betoh64(packidx->hdr.large_offsets[idx]);