fix a leak and use recallocarray in read_object_header()
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
diff --git a/lib/object.c b/lib/object.c
index b08d941..b039c61 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -191,36 +191,41 @@ read_object_header(struct got_object **obj, int fd)
char *buf;
const size_t zbsize = 64;
size_t outlen, totlen;
- int i;
+ int nbuf = 1;
buf = malloc(zbsize);
if (buf == NULL)
return got_error_from_errno();
- err = got_inflate_init(&zb, NULL, zbsize);
+ err = got_inflate_init(&zb, buf, zbsize);
if (err)
return err;
- i = 0;
totlen = 0;
do {
err = got_inflate_read_fd(&zb, fd, &outlen);
if (err)
goto done;
+ if (outlen == 0)
+ break;
+ totlen += outlen;
if (strchr(zb.outbuf, '\0') == NULL) {
- buf = reallocarray(buf, 2 + i, zbsize);
- if (buf == NULL) {
+ char *newbuf;
+ nbuf++;
+ newbuf = recallocarray(buf, nbuf - 1, nbuf, zbsize);
+ if (newbuf == NULL) {
err = got_error_from_errno();
goto done;
}
+ buf = newbuf;
+ zb.outbuf = newbuf + totlen;
+ zb.outlen = (nbuf * zbsize) - totlen;
}
- memcpy(buf + totlen, zb.outbuf, outlen);
- totlen += outlen;
- i++;
} while (strchr(zb.outbuf, '\0') == NULL);
err = parse_object_header(obj, buf, totlen);
done:
+ free(buf);
got_inflate_end(&zb);
return err;
}