fix line offset calculations in got_object_blob_dump_to_file()
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
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;
}