Commit f595d9bdb26efe762356fcc6c80608af34896240

Stefan Sperling 2019-08-14T22:51:13

fix line offset calculations in got_object_blob_dump_to_file()

diff --git a/lib/object.c b/lib/object.c
index 79ee0f0..14011f6 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -1139,7 +1139,7 @@ got_object_blob_read_block(size_t *outlenp, struct got_blob_object *blob)
 }
 
 const struct got_error *
-got_object_blob_dump_to_file(size_t *total_len, int *nlines,
+got_object_blob_dump_to_file(size_t *filesize, int *nlines,
     off_t **line_offsets, FILE *outfile, struct got_blob_object *blob)
 {
 	const struct got_error *err = NULL;
@@ -1147,12 +1147,12 @@ got_object_blob_dump_to_file(size_t *total_len, int *nlines,
 	const uint8_t *buf;
 	int i;
 	size_t noffsets = 0;
-	off_t off = 0;
+	off_t off = 0, total_len = 0;
 
 	if (line_offsets)
 		*line_offsets = NULL;
-	if (total_len)
-		*total_len = 0;
+	if (filesize)
+		*filesize = 0;
 	if (nlines)
 		*nlines = 0;
 
@@ -1169,15 +1169,15 @@ got_object_blob_dump_to_file(size_t *total_len, int *nlines,
 				/* Have some data but perhaps no '\n'. */
 				noffsets = 1;
 				*nlines = 1;
-				*line_offsets = malloc(sizeof(**line_offsets));
+				*line_offsets = calloc(1, sizeof(**line_offsets));
 				if (*line_offsets == NULL)
 					return got_error_from_errno("malloc");
-				(*line_offsets)[0] = 0;
 			}
 			/* Scan '\n' offsets in this chunk of data. */
 			for (i = hdrlen; i < len; i++) {
-				if (i > hdrlen && buf[i] == '\n')
-					(*nlines)++;
+				if (buf[i] != '\n')
+					continue;
+				(*nlines)++;
 				if (noffsets < *nlines) {
 					off_t *o = recallocarray(*line_offsets,
 					    noffsets, *nlines,
@@ -1191,19 +1191,15 @@ got_object_blob_dump_to_file(size_t *total_len, int *nlines,
 					*line_offsets = o;
 					noffsets = *nlines;
 				}
-				if (total_len) {
-					(*line_offsets)[*nlines - 1] = off;
-					off = *total_len + i -
-					    got_object_blob_get_hdrlen(blob);
-				}
+				off = total_len + i - hdrlen + 1;
+				(*line_offsets)[*nlines - 1] = off;
 			}
 		}
 		/* Skip blob object header first time around. */
 		n = fwrite(buf + hdrlen, 1, len - hdrlen, outfile);
 		if (n != len - hdrlen)
 			return got_ferror(outfile, GOT_ERR_IO);
-		if (total_len)
-			*total_len += len - hdrlen;
+		total_len += len - hdrlen;
 		hdrlen = 0;
 	} while (len != 0);
 
@@ -1211,6 +1207,9 @@ got_object_blob_dump_to_file(size_t *total_len, int *nlines,
 		return got_error_from_errno("fflush");
 	rewind(outfile);
 
+	if (filesize)
+		*filesize = total_len;
+
 	return NULL;
 }