]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reftable/writer: handle allocation failures in `writer_index_hash()`
authorPatrick Steinhardt <ps@pks.im>
Wed, 2 Oct 2024 10:55:45 +0000 (12:55 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 2 Oct 2024 14:53:52 +0000 (07:53 -0700)
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>
reftable/writer.c

index 9d5e6072bc6116e2be292cc39a406bc7bd9e1c90..ed61aaf59c59ab54cbfea20ac6ff0e7696ec2c3e 100644 (file)
@@ -186,18 +186,22 @@ static int obj_index_tree_node_compare(const void *a, const void *b)
                          &((const struct obj_index_tree_node *)b)->hash);
 }
 
-static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
+static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
 {
        uint64_t off = w->next;
-
        struct obj_index_tree_node want = { .hash = *hash };
+       struct obj_index_tree_node *key;
+       struct tree_node *node;
 
-       struct tree_node *node = tree_search(&want, &w->obj_index_tree,
-                                            &obj_index_tree_node_compare, 0);
-       struct obj_index_tree_node *key = NULL;
+       node = tree_search(&want, &w->obj_index_tree,
+                          &obj_index_tree_node_compare, 0);
        if (!node) {
                struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
-               key = reftable_malloc(sizeof(struct obj_index_tree_node));
+
+               key = reftable_malloc(sizeof(*key));
+               if (!key)
+                       return REFTABLE_OUT_OF_MEMORY_ERROR;
+
                *key = empty;
 
                strbuf_reset(&key->hash);
@@ -208,12 +212,15 @@ static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash)
                key = node->key;
        }
 
-       if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off) {
-               return;
-       }
+       if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off)
+               return 0;
 
        REFTABLE_ALLOC_GROW(key->offsets, key->offset_len + 1, key->offset_cap);
+       if (!key->offsets)
+               return REFTABLE_OUT_OF_MEMORY_ERROR;
        key->offsets[key->offset_len++] = off;
+
+       return 0;
 }
 
 static int writer_add_record(struct reftable_writer *w,
@@ -284,11 +291,11 @@ int reftable_writer_add_ref(struct reftable_writer *w,
                        .ref = *ref
                },
        };
-       int err = 0;
+       struct strbuf buf = STRBUF_INIT;
+       int err;
 
-       if (!ref->refname)
-               return REFTABLE_API_ERROR;
-       if (ref->update_index < w->min_update_index ||
+       if (!ref->refname ||
+           ref->update_index < w->min_update_index ||
            ref->update_index > w->max_update_index)
                return REFTABLE_API_ERROR;
 
@@ -296,24 +303,32 @@ int reftable_writer_add_ref(struct reftable_writer *w,
 
        err = writer_add_record(w, &rec);
        if (err < 0)
-               return err;
+               goto out;
 
        if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) {
-               struct strbuf h = STRBUF_INIT;
-               strbuf_add(&h, (char *)reftable_ref_record_val1(ref),
+               strbuf_add(&buf, (char *)reftable_ref_record_val1(ref),
                           hash_size(w->opts.hash_id));
-               writer_index_hash(w, &h);
-               strbuf_release(&h);
+
+               err = writer_index_hash(w, &buf);
+               if (err < 0)
+                       goto out;
        }
 
        if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) {
-               struct strbuf h = STRBUF_INIT;
-               strbuf_add(&h, reftable_ref_record_val2(ref),
+               strbuf_reset(&buf);
+               strbuf_add(&buf, reftable_ref_record_val2(ref),
                           hash_size(w->opts.hash_id));
-               writer_index_hash(w, &h);
-               strbuf_release(&h);
+
+               err = writer_index_hash(w, &buf);
+               if (err < 0)
+                       goto out;
        }
-       return 0;
+
+       err = 0;
+
+out:
+       strbuf_release(&buf);
+       return err;
 }
 
 int reftable_writer_add_refs(struct reftable_writer *w,