commit - 6395114c60289f3ac0f28c0fc4b5dfcef8690cdf
commit + f18c433aae68e5537cf67eae05c0343e970307ad
blob - 280287ef843efeb4547446a984e2d924c66f9374
blob + 2c612a33c5d96977b8bbe4ac08c2fc41cc78381b
--- lib/pack.c
+++ lib/pack.c
const struct got_error *err = NULL;
struct got_delta *delta;
uint8_t *base_buf = NULL, *accum_buf = NULL, *delta_buf;
- size_t base_bufsz = 0, accum_size = 0, delta_len;
- uint64_t max_size;
+ size_t base_bufsz = 0, accum_bufsz = 0, accum_size = 0, delta_len;
+ uint64_t max_size = 0;
int n = 0;
*outbuf = NULL;
if (STAILQ_EMPTY(&deltas->entries))
return got_error(GOT_ERR_BAD_DELTA_CHAIN);
-
- err = got_pack_get_delta_chain_max_size(&max_size, deltas, pack);
- if (err)
- return err;
- accum_buf = malloc(max_size);
- if (accum_buf == NULL)
- return got_error_from_errno("malloc");
/* Deltas are ordered in ascending order. */
STAILQ_FOREACH(delta, &deltas->entries, entry) {
+ uint64_t base_size, result_size = 0;
int cached = 1;
if (n == 0) {
size_t delta_data_offset;
err = got_error(GOT_ERR_PACK_OFFSET);
goto done;
}
+
+ if (delta->size > max_size)
+ max_size = delta->size;
+
if (pack->map) {
size_t mapoff = (size_t)delta_data_offset;
err = got_inflate_to_mem_mmap(&base_buf,
goto done;
}
}
+
+ err = got_delta_get_sizes(&base_size, &result_size,
+ delta_buf, delta_len);
+ if (err)
+ goto done;
+ if (base_size > max_size)
+ max_size = base_size;
+ if (result_size > max_size)
+ max_size = result_size;
+
+ if (max_size > base_bufsz) {
+ uint8_t *p = realloc(base_buf, max_size);
+ if (p == NULL) {
+ err = got_error_from_errno("realloc");
+ goto done;
+ }
+ base_buf = p;
+ base_bufsz = max_size;
+ }
+
+ if (max_size > accum_bufsz) {
+ uint8_t *p = realloc(accum_buf, max_size);
+ if (p == NULL) {
+ err = got_error_from_errno("realloc");
+ goto done;
+ }
+ accum_buf = p;
+ accum_bufsz = max_size;
+ }
+
err = got_delta_apply_in_mem(base_buf, base_bufsz,
delta_buf, delta_len, accum_buf,
&accum_size, max_size);
if (n < deltas->nentries) {
/* Accumulated delta becomes the new base. */
uint8_t *tmp = accum_buf;
- /*
- * Base buffer switches roles with accumulation buffer.
- * Ensure it can hold the largest result in the delta
- * chain. Initial allocation might have been smaller.
- */
- if (base_bufsz < max_size) {
- uint8_t *p;
- p = reallocarray(base_buf, 1, max_size);
- if (p == NULL) {
- err = got_error_from_errno(
- "reallocarray");
- goto done;
- }
- base_buf = p;
- base_bufsz = max_size;
- }
+ size_t tmp_size = accum_bufsz;
accum_buf = base_buf;
+ accum_bufsz = base_bufsz;
base_buf = tmp;
+ base_bufsz = tmp_size;
}
}