Commit 61d262a8cb97715b621fe46595c9b84e04d7f8ec

Stefan Sperling 2018-02-11T16:37:53

make got_inflate_read() properly indicate if it needs to be called again

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 *);