reftable/writer: handle allocation failures in `writer_index_hash()`
Handle allocation errors in `writer_index_hash()`. Adjust its only caller in `reftable_writer_add_ref()` accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
Oct 2, 2024 at 12:55 UTC
b680af2dba27f851d3cea2000094a1dc42f38cd2
1 file changed
+38
-23
reftable/writer.c
+38
-23
@@ -186,18 +186,22 @@ static int obj_index_tree_node_compare(const void *a, const void *b)
186
&((const struct obj_index_tree_node *)b)->hash);
187
}
188
189
-static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
189
+static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
190
{
191
uint64_t off = w->next;
192
-
192
struct obj_index_tree_node want = { .hash = *hash };
193
+ struct obj_index_tree_node *key;
194
+ struct tree_node *node;
195
195
- struct tree_node *node = tree_search(&want, &w->obj_index_tree,
196
- &obj_index_tree_node_compare, 0);
197
- struct obj_index_tree_node *key = NULL;
196
+ node = tree_search(&want, &w->obj_index_tree,
197
+ &obj_index_tree_node_compare, 0);
198
if (!node) {
199
struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
200
- key = reftable_malloc(sizeof(struct obj_index_tree_node));
200
+
201
+ key = reftable_malloc(sizeof(*key));
202
+ if (!key)
203
+ return REFTABLE_OUT_OF_MEMORY_ERROR;
204
+
205
*key = empty;
206
207
strbuf_reset(&key->hash);
@@ -208,12 +212,15 @@ static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
212
key = node->key;
213
}
214
211
- if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off) {
212
- return;
213
- }
215
+ if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off)
216
+ return 0;
217
218
REFTABLE_ALLOC_GROW(key->offsets, key->offset_len + 1, key->offset_cap);
219
+ if (!key->offsets)
220
+ return REFTABLE_OUT_OF_MEMORY_ERROR;
221
key->offsets[key->offset_len++] = off;
222
+
223
+ return 0;
224
}
225
226
static int writer_add_record(struct reftable_writer *w,
@@ -284,11 +291,11 @@ int reftable_writer_add_ref(struct reftable_writer *w,
291
.ref = *ref
292
},
293
};
287
- int err = 0;
294
+ struct strbuf buf = STRBUF_INIT;
295
+ int err;
296
289
- if (!ref->refname)
290
- return REFTABLE_API_ERROR;
291
- if (ref->update_index < w->min_update_index ||
297
+ if (!ref->refname ||
298
+ ref->update_index < w->min_update_index ||
299
ref->update_index > w->max_update_index)
300
return REFTABLE_API_ERROR;
301
@@ -296,24 +303,32 @@ int reftable_writer_add_ref(struct reftable_writer *w,
303
304
err = writer_add_record(w, &rec);
305
if (err < 0)
299
- return err;
306
+ goto out;
307
308
if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) {
302
- struct strbuf h = STRBUF_INIT;
303
- strbuf_add(&h, (char *)reftable_ref_record_val1(ref),
309
+ strbuf_add(&buf, (char *)reftable_ref_record_val1(ref),
310
hash_size(w->opts.hash_id));
305
- writer_index_hash(w, &h);
306
- strbuf_release(&h);
311
+
312
+ err = writer_index_hash(w, &buf);
313
+ if (err < 0)
314
+ goto out;
315
}
316
317
if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) {
310
- struct strbuf h = STRBUF_INIT;
311
- strbuf_add(&h, reftable_ref_record_val2(ref),
318
+ strbuf_reset(&buf);
319
+ strbuf_add(&buf, reftable_ref_record_val2(ref),
320
hash_size(w->opts.hash_id));
313
- writer_index_hash(w, &h);
314
- strbuf_release(&h);
321
+
322
+ err = writer_index_hash(w, &buf);
323
+ if (err < 0)
324
+ goto out;
325
}
316
- return 0;
326
+
327
+ err = 0;
328
+
329
+out:
330
+ strbuf_release(&buf);
331
+ return err;
332
}
333
334
int reftable_writer_add_refs(struct reftable_writer *w,