reftable/record: adapt `reftable_record_key()` to handle allocation failures

The `reftable_record_key()` function cannot pass any errors to the caller as it has a `void` return type. Adapt it and its callers such that we can handle errors and start handling allocation failures. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>

Patrick Steinhardt committed Oct 17, 2024 at 06:54 UTC 4abc8022ffae64bb24e93153c75bc880991bb2dc
5 files changed +47 -22
reftable/block.c
+15 -5
@@ -111,9 +111,12 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
111 int is_restart = 0;
112 struct reftable_buf key = REFTABLE_BUF_INIT;
113 int n = 0;
114 - int err = -1;
114 + int err;
115 +
116 + err = reftable_record_key(rec, &key);
117 + if (err < 0)
118 + goto done;
119
116 - reftable_record_key(rec, &key);
120 if (!key.len) {
121 err = REFTABLE_API_ERROR;
122 goto done;
@@ -121,13 +124,17 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
124
125 n = reftable_encode_key(&is_restart, out, last, key,
126 reftable_record_val_type(rec));
124 - if (n < 0)
127 + if (n < 0) {
128 + err = -1;
129 goto done;
130 + }
131 string_view_consume(&out, n);
132
133 n = reftable_record_encode(rec, out, w->hash_size);
129 - if (n < 0)
134 + if (n < 0) {
135 + err = -1;
136 goto done;
137 + }
138 string_view_consume(&out, n);
139
140 err = block_writer_register_restart(w, start.len - out.len, is_restart,
@@ -522,6 +529,10 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
529 goto done;
530 }
531
532 + err = reftable_record_key(&rec, &it->last_key);
533 + if (err < 0)
534 + goto done;
535 +
536 /*
537 * Check whether the current key is greater or equal to the
538 * sought-after key. In case it is greater we know that the
@@ -536,7 +547,6 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
547 * to `last_key` now, and naturally all keys share a prefix
548 * with themselves.
549 */
539 - reftable_record_key(&rec, &it->last_key);
550 if (reftable_buf_cmp(&it->last_key, want) >= 0) {
551 it->next_off = prev_off;
552 goto done;
reftable/reader.c
+6 -2
@@ -356,7 +356,9 @@ static int table_iter_seek_linear(struct table_iter *ti,
356 int err;
357
358 reftable_record_init(&rec, reftable_record_type(want));
359 - reftable_record_key(want, &want_key);
359 + err = reftable_record_key(want, &want_key);
360 + if (err < 0)
361 + goto done;
362
363 /*
364 * First we need to locate the block that must contain our record. To
@@ -439,7 +441,9 @@ static int table_iter_seek_indexed(struct table_iter *ti,
441 };
442 int err;
443
442 - reftable_record_key(rec, &want_index.u.idx.last_key);
444 + err = reftable_record_key(rec, &want_index.u.idx.last_key);
445 + if (err < 0)
446 + goto done;
447
448 /*
449 * The index may consist of multiple levels, where each level may have
reftable/record.c
+20 -12
@@ -207,12 +207,12 @@ int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra,
207 return start_len - in.len;
208 }
209
210 -static void reftable_ref_record_key(const void *r, struct reftable_buf *dest)
210 +static int reftable_ref_record_key(const void *r, struct reftable_buf *dest)
211 {
212 const struct reftable_ref_record *rec =
213 (const struct reftable_ref_record *)r;
214 reftable_buf_reset(dest);
215 - reftable_buf_addstr(dest, rec->refname);
215 + return reftable_buf_addstr(dest, rec->refname);
216 }
217
218 static int reftable_ref_record_copy_from(void *rec, const void *src_rec,
@@ -465,12 +465,12 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
465 .cmp = &reftable_ref_record_cmp_void,
466 };
467
468 -static void reftable_obj_record_key(const void *r, struct reftable_buf *dest)
468 +static int reftable_obj_record_key(const void *r, struct reftable_buf *dest)
469 {
470 const struct reftable_obj_record *rec =
471 (const struct reftable_obj_record *)r;
472 reftable_buf_reset(dest);
473 - reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
473 + return reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
474 }
475
476 static void reftable_obj_record_release(void *rec)
@@ -664,19 +664,27 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
664 .cmp = &reftable_obj_record_cmp_void,
665 };
666
667 -static void reftable_log_record_key(const void *r, struct reftable_buf *dest)
667 +static int reftable_log_record_key(const void *r, struct reftable_buf *dest)
668 {
669 const struct reftable_log_record *rec =
670 (const struct reftable_log_record *)r;
671 - int len = strlen(rec->refname);
671 + int len = strlen(rec->refname), err;
672 uint8_t i64[8];
673 uint64_t ts = 0;
674 +
675 reftable_buf_reset(dest);
675 - reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1);
676 + err = reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1);
677 + if (err < 0)
678 + return err;
679
680 ts = (~ts) - rec->update_index;
681 put_be64(&i64[0], ts);
679 - reftable_buf_add(dest, i64, sizeof(i64));
682 +
683 + err = reftable_buf_add(dest, i64, sizeof(i64));
684 + if (err < 0)
685 + return err;
686 +
687 + return 0;
688 }
689
690 static int reftable_log_record_copy_from(void *rec, const void *src_rec,
@@ -1027,11 +1035,11 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
1035 .cmp = &reftable_log_record_cmp_void,
1036 };
1037
1030 -static void reftable_index_record_key(const void *r, struct reftable_buf *dest)
1038 +static int reftable_index_record_key(const void *r, struct reftable_buf *dest)
1039 {
1040 const struct reftable_index_record *rec = r;
1041 reftable_buf_reset(dest);
1034 - reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len);
1042 + return reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len);
1043 }
1044
1045 static int reftable_index_record_copy_from(void *rec, const void *src_rec,
@@ -1124,9 +1132,9 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
1132 .cmp = &reftable_index_record_cmp,
1133 };
1134
1127 -void reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest)
1135 +int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest)
1136 {
1129 - reftable_record_vtable(rec)->key(reftable_record_data(rec), dest);
1137 + return reftable_record_vtable(rec)->key(reftable_record_data(rec), dest);
1138 }
1139
1140 int reftable_record_encode(struct reftable_record *rec, struct string_view dest,
reftable/record.h
+2 -2
@@ -40,7 +40,7 @@ int put_var_int(struct string_view *dest, uint64_t val);
40 /* Methods for records. */
41 struct reftable_record_vtable {
42 /* encode the key of to a uint8_t reftable_buf. */
43 - void (*key)(const void *rec, struct reftable_buf *dest);
43 + int (*key)(const void *rec, struct reftable_buf *dest);
44
45 /* The record type of ('r' for ref). */
46 uint8_t type;
@@ -137,7 +137,7 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ);
137 /* see struct record_vtable */
138 int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b);
139 int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
140 -void reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest);
140 +int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest);
141 int reftable_record_copy_from(struct reftable_record *rec,
142 struct reftable_record *src, int hash_size);
143 uint8_t reftable_record_val_type(struct reftable_record *rec);
reftable/writer.c
+4 -1
@@ -249,7 +249,10 @@ static int writer_add_record(struct reftable_writer *w,
249 struct reftable_buf key = REFTABLE_BUF_INIT;
250 int err;
251
252 - reftable_record_key(rec, &key);
252 + err = reftable_record_key(rec, &key);
253 + if (err < 0)
254 + goto done;
255 +
256 if (reftable_buf_cmp(&w->last_key, &key) >= 0) {
257 err = REFTABLE_API_ERROR;
258 goto done;