Commit 3ab5e33ce18309779415bf4e5e2464cbf01b06ac

Stefan Sperling 2020-03-18T16:13:41

add optional 'consumed' output parameter to got_inflate_to_mem_fd()

diff --git a/lib/got_lib_inflate.h b/lib/got_lib_inflate.h
index 90304d5..d8d1ad0 100644
--- a/lib/got_lib_inflate.h
+++ b/lib/got_lib_inflate.h
@@ -32,13 +32,14 @@ const struct got_error *got_inflate_init(struct got_inflate_buf *, uint8_t *,
 const struct got_error *got_inflate_read(struct got_inflate_buf *, FILE *,
     size_t *, size_t *);
 const struct got_error *got_inflate_read_fd(struct got_inflate_buf *, int,
-    size_t *);
+    size_t *, size_t *);
 const struct got_error *got_inflate_read_mmap(struct got_inflate_buf *,
     uint8_t *, size_t, size_t, size_t *, size_t *);
 void got_inflate_end(struct got_inflate_buf *);
 const struct got_error *got_inflate_to_mem(uint8_t **, size_t *, size_t *,
     FILE *);
-const struct got_error *got_inflate_to_mem_fd(uint8_t **, size_t *, int);
+const struct got_error *got_inflate_to_mem_fd(uint8_t **, size_t *, size_t *,
+    int);
 const struct got_error *got_inflate_to_mem_mmap(uint8_t **, size_t *, uint8_t *,
     size_t, size_t);
 const struct got_error *got_inflate_to_file(size_t *, FILE *, FILE *);
diff --git a/lib/inflate.c b/lib/inflate.c
index 02b01b5..75a81b0 100644
--- a/lib/inflate.c
+++ b/lib/inflate.c
@@ -126,9 +126,11 @@ got_inflate_read(struct got_inflate_buf *zb, FILE *f, size_t *outlenp,
 }
 
 const struct got_error *
-got_inflate_read_fd(struct got_inflate_buf *zb, int fd, size_t *outlenp)
+got_inflate_read_fd(struct got_inflate_buf *zb, int fd, size_t *outlenp,
+    size_t *consumed)
 {
 	size_t last_total_out = zb->z.total_out;
+	size_t last_total_in = zb->z.total_in;
 	z_stream *z = &zb->z;
 	int ret = Z_ERRNO;
 
@@ -136,6 +138,8 @@ got_inflate_read_fd(struct got_inflate_buf *zb, int fd, size_t *outlenp)
 	z->avail_out = zb->outlen;
 
 	*outlenp = 0;
+	if (consumed)
+		*consumed = 0;
 	do {
 		if (z->avail_in == 0) {
 			ssize_t n = read(fd, zb->inbuf, zb->inlen);
@@ -161,6 +165,8 @@ got_inflate_read_fd(struct got_inflate_buf *zb, int fd, size_t *outlenp)
 	}
 
 	*outlenp = z->total_out - last_total_out;
+	if (consumed)
+		*consumed += z->total_in - last_total_in;
 	return NULL;
 }
 
@@ -264,10 +270,11 @@ done:
 }
 
 const struct got_error *
-got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen, int infd)
+got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen,
+    size_t *consumed_total, int infd)
 {
 	const struct got_error *err;
-	size_t avail;
+	size_t avail, consumed;
 	struct got_inflate_buf zb;
 	void *newbuf;
 	int nbuf = 1;
@@ -280,12 +287,16 @@ got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen, int infd)
 		goto done;
 
 	*outlen = 0;
+	if (consumed_total)
+		*consumed_total = 0;
 
 	do {
-		err = got_inflate_read_fd(&zb, infd, &avail);
+		err = got_inflate_read_fd(&zb, infd, &avail, &consumed);
 		if (err)
 			goto done;
 		*outlen += avail;
+		if (consumed_total)
+			*consumed_total += consumed;
 		if (zb.flags & GOT_INFLATE_F_HAVE_MORE) {
 			newbuf = reallocarray(*outbuf, ++nbuf,
 			    GOT_INFLATE_BUFSIZE);
@@ -445,7 +456,7 @@ got_inflate_to_file_fd(size_t *outlen, int infd, FILE *outfile)
 	*outlen = 0;
 
 	do {
-		err = got_inflate_read_fd(&zb, infd, &avail);
+		err = got_inflate_read_fd(&zb, infd, &avail, NULL);
 		if (err)
 			goto done;
 		if (avail > 0) {
diff --git a/lib/object_parse.c b/lib/object_parse.c
index d358412..a4a82ed 100644
--- a/lib/object_parse.c
+++ b/lib/object_parse.c
@@ -227,7 +227,7 @@ got_object_read_header(struct got_object **obj, int fd)
 
 	totlen = 0;
 	do {
-		err = got_inflate_read_fd(&zb, fd, &outlen);
+		err = got_inflate_read_fd(&zb, fd, &outlen, NULL);
 		if (err)
 			goto done;
 		if (outlen == 0)
diff --git a/lib/pack.c b/lib/pack.c
index bc26681..c2147b8 100644
--- a/lib/pack.c
+++ b/lib/pack.c
@@ -723,7 +723,8 @@ read_delta_data(uint8_t **delta_buf, size_t *delta_len,
 	} else {
 		if (lseek(pack->fd, delta_data_offset, SEEK_SET) == -1)
 			return got_error_from_errno("lseek");
-		err = got_inflate_to_mem_fd(delta_buf, delta_len, pack->fd);
+		err = got_inflate_to_mem_fd(delta_buf, delta_len, NULL,
+		    pack->fd);
 	}
 	return err;
 }
@@ -823,6 +824,10 @@ resolve_ref_delta(struct got_delta_chain *deltas, struct got_packidx *packidx,
 		delta_data_offset = lseek(pack->fd, 0, SEEK_CUR);
 		if (delta_data_offset == -1)
 			return got_error_from_errno("lseek");
+		err = got_inflate_to_mem_fd(&delta_buf, &delta_len, NULL,
+		    pack->fd);
+		if (err)
+			return err;
 	}
 
 	err = add_delta(deltas, delta_offset, tslen, delta_type, delta_size,
@@ -1102,7 +1107,7 @@ dump_delta_chain_to_file(size_t *result_size, struct got_delta_chain *deltas,
 					    pack->filesize - mapoff);
 				} else
 					err = got_inflate_to_mem_fd(&base_buf,
-					    &base_bufsz, pack->fd);
+					    &base_bufsz, NULL, pack->fd);
 			}
 			if (err)
 				goto done;
@@ -1249,7 +1254,7 @@ dump_delta_chain_to_mem(uint8_t **outbuf, size_t *outlen,
 					goto done;
 				}
 				err = got_inflate_to_mem_fd(&base_buf,
-				    &base_bufsz, pack->fd);
+				    &base_bufsz, NULL, pack->fd);
 			}
 			if (err)
 				goto done;
@@ -1369,7 +1374,7 @@ got_packfile_extract_object_to_mem(uint8_t **buf, size_t *len,
 		} else {
 			if (lseek(pack->fd, obj->pack_offset, SEEK_SET) == -1)
 				return got_error_from_errno("lseek");
-			err = got_inflate_to_mem_fd(buf, len, pack->fd);
+			err = got_inflate_to_mem_fd(buf, len, NULL, pack->fd);
 		}
 	} else
 		err = dump_delta_chain_to_mem(buf, len, &obj->deltas, pack);