make got_inflate_read() properly indicate if it needs to be called again
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
diff --git a/lib/pack.c b/lib/pack.c
index 9e010e0..e53d687 100644
--- a/lib/pack.c
+++ b/lib/pack.c
@@ -839,8 +839,7 @@ dump_delta_chain(struct got_delta_chain *deltas, FILE *outfile)
}
/* Delta streams should always fit in memory. */
- err = got_inflate_to_mem(&delta_buf, &delta_len, delta_file,
- delta->size);
+ err = got_inflate_to_mem(&delta_buf, &delta_len, delta_file);
if (err)
return err;
diff --git a/lib/zb.c b/lib/zb.c
index 16623c1..0d9155f 100644
--- a/lib/zb.c
+++ b/lib/zb.c
@@ -92,10 +92,12 @@ got_inflate_read(struct got_zstream_buf *zb, FILE *f, size_t *inlenp,
ret = inflate(z, Z_SYNC_FLUSH);
} while (ret == Z_OK && z->avail_out > 0);
- if (ret != Z_OK) {
+ if (ret == Z_OK) {
+ zb->flags |= GOT_ZSTREAM_F_HAVE_MORE;
+ } else {
if (ret != Z_STREAM_END)
return got_error(GOT_ERR_DECOMPRESSION);
- zb->flags |= GOT_ZSTREAM_F_HAVE_MORE;
+ zb->flags &= ~GOT_ZSTREAM_F_HAVE_MORE;
}
*outlenp = z->total_out - last_total_out;
@@ -111,10 +113,10 @@ got_inflate_end(struct got_zstream_buf *zb)
}
const struct got_error *
-got_inflate_to_mem(uint8_t **outbuf, size_t *outlen, FILE *f, size_t insize)
+got_inflate_to_mem(uint8_t **outbuf, size_t *outlen, FILE *f)
{
const struct got_error *err;
- size_t inbytes, consumed, avail;
+ size_t consumed, avail;
struct got_zstream_buf zb;
void *newbuf;
@@ -124,30 +126,25 @@ got_inflate_to_mem(uint8_t **outbuf, size_t *outlen, FILE *f, size_t insize)
*outbuf = NULL;
*outlen = 0;
- inbytes = 0;
- while (1) {
+ do {
err = got_inflate_read(&zb, f, &consumed, &avail);
if (err)
return err;
- inbytes += consumed;
- if (avail == 0) {
- if (insize && inbytes < insize)
- err = got_error(GOT_ERR_BAD_DELTA);
- break;
- }
- newbuf = reallocarray(*outbuf, 1, *outlen + avail);
- if (newbuf == NULL) {
- free(*outbuf);
- *outbuf = NULL;
- *outlen = 0;
- err = got_error(GOT_ERR_NO_MEM);
- goto done;
+ if (avail > 0) {
+ newbuf = reallocarray(*outbuf, 1, *outlen + avail);
+ if (newbuf == NULL) {
+ free(*outbuf);
+ *outbuf = NULL;
+ *outlen = 0;
+ err = got_error(GOT_ERR_NO_MEM);
+ goto done;
+ }
+ memcpy(newbuf + *outlen, zb.outbuf, avail);
+ *outbuf = newbuf;
+ *outlen += avail;
}
- memcpy(newbuf + *outlen, zb.outbuf, avail);
- *outbuf = newbuf;
- *outlen += avail;
- };
+ } while (zb.flags & GOT_ZSTREAM_F_HAVE_MORE);
done:
got_inflate_end(&zb);
diff --git a/lib/zb.h b/lib/zb.h
index f71dcda..e529401 100644
--- a/lib/zb.h
+++ b/lib/zb.h
@@ -18,6 +18,5 @@ const struct got_error *got_inflate_init(struct got_zstream_buf *, size_t);
const struct got_error *got_inflate_read(struct got_zstream_buf *, FILE *,
size_t *, size_t *);
void got_inflate_end(struct got_zstream_buf *);
-const struct got_error *got_inflate_to_mem(uint8_t **, size_t *, FILE *,
- size_t);
+const struct got_error *got_inflate_to_mem(uint8_t **, size_t *, FILE *);
const struct got_error *got_inflate_to_file(size_t *, FILE *, FILE *);