@@ -1324,7 +1324,10 @@ int git_open_cloexec(const char *name, int flags);
* unpack_loose_header() initializes the data stream needed to unpack
* a loose object header.
*
- * Returns 0 on success. Returns negative values on error.
+ * Returns:
+ *
+ * - ULHR_OK on success
+ * - ULHR_BAD on error
*
* It will only parse up to MAX_HEADER_LEN bytes unless an optional
* "hdrbuf" argument is non-NULL. This is intended for use with
@@ -1332,9 +1335,17 @@ int git_open_cloexec(const char *name, int flags);
* reporting. The full header will be extracted to "hdrbuf" for use
* with parse_loose_header().
*/
-int unpack_loose_header(git_zstream *stream, unsigned char *map,
- unsigned long mapsize, void *buffer,
- unsigned long bufsiz, struct strbuf *hdrbuf);
+enum unpack_loose_header_result {
+ ULHR_OK,
+ ULHR_BAD,
+};
+enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
+ unsigned char *map,
+ unsigned long mapsize,
+ void *buffer,
+ unsigned long bufsiz,
+ struct strbuf *hdrbuf);
+
struct object_info;
int parse_loose_header(const char *hdr, struct object_info *oi,
unsigned int flags);
@@ -1255,10 +1255,12 @@ void *map_loose_object(struct repository *r,
return map_loose_object_1(r, NULL, oid, size);
}
-int unpack_loose_header(git_zstream *stream,
- unsigned char *map, unsigned long mapsize,
- void *buffer, unsigned long bufsiz,
- struct strbuf *header)
+enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
+ unsigned char *map,
+ unsigned long mapsize,
+ void *buffer,
+ unsigned long bufsiz,
+ struct strbuf *header)
{
int status;
@@ -1274,13 +1276,13 @@ int unpack_loose_header(git_zstream *stream,
status = git_inflate(stream, 0);
obj_read_lock();
if (status < Z_OK)
- return -1;
+ return ULHR_BAD;
/*
* Check if entire header is unpacked in the first iteration.
*/
if (memchr(buffer, '\0', stream->next_out - (unsigned char *)buffer))
- return 0;
+ return ULHR_OK;
/*
* We have a header longer than MAX_HEADER_LEN. The "header"
@@ -1288,7 +1290,7 @@ int unpack_loose_header(git_zstream *stream,
* --allow-unknown-type".
*/
if (!header)
- return -1;
+ return ULHR_BAD;
/*
* buffer[0..bufsiz] was not large enough. Copy the partial
@@ -1309,7 +1311,7 @@ int unpack_loose_header(git_zstream *stream,
stream->next_out = buffer;
stream->avail_out = bufsiz;
} while (status != Z_STREAM_END);
- return -1;
+ return ULHR_BAD;
}
static void *unpack_loose_rest(git_zstream *stream,
@@ -1474,13 +1476,19 @@ static int loose_object_info(struct repository *r,
if (oi->disk_sizep)
*oi->disk_sizep = mapsize;
- if (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr),
- allow_unknown ? &hdrbuf : NULL) < 0)
+ switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr),
+ allow_unknown ? &hdrbuf : NULL)) {
+ case ULHR_OK:
+ break;
+ case ULHR_BAD:
status = error(_("unable to unpack %s header"),
oid_to_hex(oid));
- if (status < 0)
- ; /* Do nothing */
- else if (hdrbuf.len) {
+ break;
+ }
+
+ if (status < 0) {
+ /* Do nothing */
+ } else if (hdrbuf.len) {
if ((status = parse_loose_header(hdrbuf.buf, oi, flags)) < 0)
status = error(_("unable to parse %s header with --allow-unknown-type"),
oid_to_hex(oid));
@@ -229,17 +229,16 @@ static int open_istream_loose(struct git_istream *st, struct repository *r,
st->u.loose.mapped = map_loose_object(r, oid, &st->u.loose.mapsize);
if (!st->u.loose.mapped)
return -1;
- if ((unpack_loose_header(&st->z,
- st->u.loose.mapped,
- st->u.loose.mapsize,
- st->u.loose.hdr,
- sizeof(st->u.loose.hdr),
- NULL) < 0) ||
- (parse_loose_header(st->u.loose.hdr, &oi, 0) < 0)) {
- git_inflate_end(&st->z);
- munmap(st->u.loose.mapped, st->u.loose.mapsize);
- return -1;
+ switch (unpack_loose_header(&st->z, st->u.loose.mapped,
+ st->u.loose.mapsize, st->u.loose.hdr,
+ sizeof(st->u.loose.hdr), NULL)) {
+ case ULHR_OK:
+ break;
+ case ULHR_BAD:
+ goto error;
}
+ if (parse_loose_header(st->u.loose.hdr, &oi, 0) < 0)
+ goto error;
st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
st->u.loose.hdr_avail = st->z.total_out;
@@ -248,6 +247,10 @@ static int open_istream_loose(struct git_istream *st, struct repository *r,
st->read = read_istream_loose;
return 0;
+error:
+ git_inflate_end(&st->z);
+ munmap(st->u.loose.mapped, st->u.loose.mapsize);
+ return -1;
}
In a preceding commit we changed and documented unpack_loose_header() from its previous behavior of returning any negative value or zero, to only -1 or 0. Let's add an "enum unpack_loose_header_result" type and use it for these return values, and have the compiler assert that we're exhaustively covering all of them. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> --- cache.h | 19 +++++++++++++++---- object-file.c | 34 +++++++++++++++++++++------------- streaming.c | 23 +++++++++++++---------- 3 files changed, 49 insertions(+), 27 deletions(-)