object-file.c: use "enum" return type for unpack_loose_header()
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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ævar Arnfjörð Bjarmason committed
Oct 1, 2021 at 11:16 UTC
3b6a8db3b03adb118bfafb90bbc710068dbd6d14
3 files changed
+49
-27
cache.h
+15
-4
@@ -1307,7 +1307,10 @@ int git_open_cloexec(const char *name, int flags);
1307
* unpack_loose_header() initializes the data stream needed to unpack
1308
* a loose object header.
1309
*
1310
- * Returns 0 on success. Returns negative values on error.
1310
+ * Returns:
1311
+ *
1312
+ * - ULHR_OK on success
1313
+ * - ULHR_BAD on error
1314
*
1315
* It will only parse up to MAX_HEADER_LEN bytes unless an optional
1316
* "hdrbuf" argument is non-NULL. This is intended for use with
@@ -1315,9 +1318,17 @@ int git_open_cloexec(const char *name, int flags);
1318
* reporting. The full header will be extracted to "hdrbuf" for use
1319
* with parse_loose_header().
1320
*/
1318
-int unpack_loose_header(git_zstream *stream, unsigned char *map,
1319
- unsigned long mapsize, void *buffer,
1320
- unsigned long bufsiz, struct strbuf *hdrbuf);
1321
+enum unpack_loose_header_result {
1322
+ ULHR_OK,
1323
+ ULHR_BAD,
1324
+};
1325
+enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
1326
+ unsigned char *map,
1327
+ unsigned long mapsize,
1328
+ void *buffer,
1329
+ unsigned long bufsiz,
1330
+ struct strbuf *hdrbuf);
1331
+
1332
struct object_info;
1333
int parse_loose_header(const char *hdr, struct object_info *oi,
1334
unsigned int flags);
object-file.c
+21
-13
@@ -1210,10 +1210,12 @@ void *map_loose_object(struct repository *r,
1210
return map_loose_object_1(r, NULL, oid, size);
1211
}
1212
1213
-int unpack_loose_header(git_zstream *stream,
1214
- unsigned char *map, unsigned long mapsize,
1215
- void *buffer, unsigned long bufsiz,
1216
- struct strbuf *header)
1213
+enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
1214
+ unsigned char *map,
1215
+ unsigned long mapsize,
1216
+ void *buffer,
1217
+ unsigned long bufsiz,
1218
+ struct strbuf *header)
1219
{
1220
int status;
1221
@@ -1229,13 +1231,13 @@ int unpack_loose_header(git_zstream *stream,
1231
status = git_inflate(stream, 0);
1232
obj_read_lock();
1233
if (status < Z_OK)
1232
- return -1;
1234
+ return ULHR_BAD;
1235
1236
/*
1237
* Check if entire header is unpacked in the first iteration.
1238
*/
1239
if (memchr(buffer, '\0', stream->next_out - (unsigned char *)buffer))
1238
- return 0;
1240
+ return ULHR_OK;
1241
1242
/*
1243
* We have a header longer than MAX_HEADER_LEN. The "header"
@@ -1243,7 +1245,7 @@ int unpack_loose_header(git_zstream *stream,
1245
* --allow-unknown-type".
1246
*/
1247
if (!header)
1246
- return -1;
1248
+ return ULHR_BAD;
1249
1250
/*
1251
* buffer[0..bufsiz] was not large enough. Copy the partial
@@ -1264,7 +1266,7 @@ int unpack_loose_header(git_zstream *stream,
1266
stream->next_out = buffer;
1267
stream->avail_out = bufsiz;
1268
} while (status != Z_STREAM_END);
1267
- return -1;
1269
+ return ULHR_BAD;
1270
}
1271
1272
static void *unpack_loose_rest(git_zstream *stream,
@@ -1429,13 +1431,19 @@ static int loose_object_info(struct repository *r,
1431
if (oi->disk_sizep)
1432
*oi->disk_sizep = mapsize;
1433
1432
- if (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr),
1433
- allow_unknown ? &hdrbuf : NULL) < 0)
1434
+ switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr),
1435
+ allow_unknown ? &hdrbuf : NULL)) {
1436
+ case ULHR_OK:
1437
+ break;
1438
+ case ULHR_BAD:
1439
status = error(_("unable to unpack %s header"),
1440
oid_to_hex(oid));
1436
- if (status < 0)
1437
- ; /* Do nothing */
1438
- else if (hdrbuf.len) {
1441
+ break;
1442
+ }
1443
+
1444
+ if (status < 0) {
1445
+ /* Do nothing */
1446
+ } else if (hdrbuf.len) {
1447
if ((status = parse_loose_header(hdrbuf.buf, oi, flags)) < 0)
1448
status = error(_("unable to parse %s header with --allow-unknown-type"),
1449
oid_to_hex(oid));
streaming.c
+13
-10
@@ -229,17 +229,16 @@ static int open_istream_loose(struct git_istream *st, struct repository *r,
229
st->u.loose.mapped = map_loose_object(r, oid, &st->u.loose.mapsize);
230
if (!st->u.loose.mapped)
231
return -1;
232
- if ((unpack_loose_header(&st->z,
233
- st->u.loose.mapped,
234
- st->u.loose.mapsize,
235
- st->u.loose.hdr,
236
- sizeof(st->u.loose.hdr),
237
- NULL) < 0) ||
238
- (parse_loose_header(st->u.loose.hdr, &oi, 0) < 0)) {
239
- git_inflate_end(&st->z);
240
- munmap(st->u.loose.mapped, st->u.loose.mapsize);
241
- return -1;
232
+ switch (unpack_loose_header(&st->z, st->u.loose.mapped,
233
+ st->u.loose.mapsize, st->u.loose.hdr,
234
+ sizeof(st->u.loose.hdr), NULL)) {
235
+ case ULHR_OK:
236
+ break;
237
+ case ULHR_BAD:
238
+ goto error;
239
}
240
+ if (parse_loose_header(st->u.loose.hdr, &oi, 0) < 0)
241
+ goto error;
242
243
st->u.loose.hdr_used = strlen(st->u.loose.hdr) + 1;
244
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,
247
st->read = read_istream_loose;
248
249
return 0;
250
+error:
251
+ git_inflate_end(&st->z);
252
+ munmap(st->u.loose.mapped, st->u.loose.mapsize);
253
+ return -1;
254
}
255
256