reftable/record: stop using `BUG()` in `reftable_record_init()`
We're aborting the program via `BUG()` in case `reftable_record_init()` was invoked with an unknown record type. This is bad because we may now die in library code, and because it makes us depend on the Git codebase. Refactor the code such that `reftable_record_init()` can return an error code to the caller. Adapt any callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Feb 18, 2025 at 10:20 UTC
9d9fac0f34ec47cc6eafeb3e10378ab8f3310346
7 files changed
+21
-13
reftable/block.c
+3
-1
@@ -508,7 +508,9 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
508
it->block_len = br->block_len;
509
it->hash_size = br->hash_size;
510
511
- reftable_record_init(&rec, block_reader_type(br));
511
+ err = reftable_record_init(&rec, block_reader_type(br));
512
+ if (err < 0)
513
+ goto done;
514
515
/*
516
* We're looking for the last entry less than the wanted key so that
reftable/merged.c
+4
-1
@@ -253,7 +253,10 @@ int merged_table_init_iter(struct reftable_merged_table *mt,
253
}
254
255
for (size_t i = 0; i < mt->readers_len; i++) {
256
- reftable_record_init(&subiters[i].rec, typ);
256
+ ret = reftable_record_init(&subiters[i].rec, typ);
257
+ if (ret < 0)
258
+ goto out;
259
+
260
ret = reader_init_iter(mt->readers[i], &subiters[i].iter, typ);
261
if (ret < 0)
262
goto out;
reftable/reader.c
+4
-1
@@ -360,7 +360,10 @@ static int table_iter_seek_linear(struct table_iter *ti,
360
struct reftable_record rec;
361
int err;
362
363
- reftable_record_init(&rec, reftable_record_type(want));
363
+ err = reftable_record_init(&rec, reftable_record_type(want));
364
+ if (err < 0)
365
+ goto done;
366
+
367
err = reftable_record_key(want, &want_key);
368
if (err < 0)
369
goto done;
reftable/record.c
+4
-4
@@ -1306,7 +1306,7 @@ reftable_record_vtable(struct reftable_record *rec)
1306
abort();
1307
}
1308
1309
-void reftable_record_init(struct reftable_record *rec, uint8_t typ)
1309
+int reftable_record_init(struct reftable_record *rec, uint8_t typ)
1310
{
1311
memset(rec, 0, sizeof(*rec));
1312
rec->type = typ;
@@ -1315,11 +1315,11 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ)
1315
case BLOCK_TYPE_REF:
1316
case BLOCK_TYPE_LOG:
1317
case BLOCK_TYPE_OBJ:
1318
- return;
1318
+ return 0;
1319
case BLOCK_TYPE_INDEX:
1320
reftable_buf_init(&rec->u.idx.last_key);
1321
- return;
1321
+ return 0;
1322
default:
1323
- BUG("unhandled record type");
1323
+ return REFTABLE_API_ERROR;
1324
}
1325
}
reftable/record.h
+2
-2
@@ -130,8 +130,8 @@ struct reftable_record {
130
} u;
131
};
132
133
-/* Initialize the reftable record for the given type */
134
-void reftable_record_init(struct reftable_record *rec, uint8_t typ);
133
+/* Initialize the reftable record for the given type. */
134
+int reftable_record_init(struct reftable_record *rec, uint8_t typ);
135
136
/* see struct record_vtable */
137
int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b);
t/unit-tests/t-reftable-pq.c
+3
-3
@@ -32,7 +32,7 @@ static void t_pq_record(void)
32
char *last = NULL;
33
34
for (i = 0; i < N; i++) {
35
- reftable_record_init(&recs[i], BLOCK_TYPE_REF);
35
+ check(!reftable_record_init(&recs[i], BLOCK_TYPE_REF));
36
recs[i].u.ref.refname = xstrfmt("%02"PRIuMAX, (uintmax_t)i);
37
}
38
@@ -72,7 +72,7 @@ static void t_pq_index(void)
72
size_t N = ARRAY_SIZE(recs), i;
73
74
for (i = 0; i < N; i++) {
75
- reftable_record_init(&recs[i], BLOCK_TYPE_REF);
75
+ check(!reftable_record_init(&recs[i], BLOCK_TYPE_REF));
76
recs[i].u.ref.refname = (char *) "refs/heads/master";
77
}
78
@@ -111,7 +111,7 @@ static void t_merged_iter_pqueue_top(void)
111
size_t N = ARRAY_SIZE(recs), i;
112
113
for (i = 0; i < N; i++) {
114
- reftable_record_init(&recs[i], BLOCK_TYPE_REF);
114
+ check(!reftable_record_init(&recs[i], BLOCK_TYPE_REF));
115
recs[i].u.ref.refname = (char *) "refs/heads/master";
116
}
117
t/unit-tests/t-reftable-record.c
+1
-1
@@ -17,7 +17,7 @@ static void t_copy(struct reftable_record *rec)
17
uint8_t typ;
18
19
typ = reftable_record_type(rec);
20
- reftable_record_init(©, typ);
20
+ check(!reftable_record_init(©, typ));
21
reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1);
22
/* do it twice to catch memory leaks */
23
reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1);