reftable/stack: handle allocation failures in `reftable_new_stack()`

Handle allocation failures in `reftable_new_stack()`. 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:56 UTC 5dbe2662127a3c53dbbaa9ef45e6c745e3fb4337
1 file changed +26 -8
reftable/stack.c
+26 -8
@@ -56,10 +56,16 @@ static int reftable_fd_flush(void *arg)
56 int reftable_new_stack(struct reftable_stack **dest, const char *dir,
57 const struct reftable_write_options *_opts)
58 {
59 - struct reftable_stack *p = reftable_calloc(1, sizeof(*p));
59 struct strbuf list_file_name = STRBUF_INIT;
61 - struct reftable_write_options opts = {0};
62 - int err = 0;
60 + struct reftable_write_options opts = { 0 };
61 + struct reftable_stack *p;
62 + int err;
63 +
64 + p = reftable_calloc(1, sizeof(*p));
65 + if (!p) {
66 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
67 + goto out;
68 + }
69
70 if (_opts)
71 opts = *_opts;
@@ -74,15 +80,23 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir,
80
81 p->list_file = strbuf_detach(&list_file_name, NULL);
82 p->list_fd = -1;
77 - p->reftable_dir = xstrdup(dir);
83 p->opts = opts;
84 + p->reftable_dir = reftable_strdup(dir);
85 + if (!p->reftable_dir) {
86 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
87 + goto out;
88 + }
89
90 err = reftable_stack_reload_maybe_reuse(p, 1);
81 - if (err < 0) {
91 + if (err < 0)
92 + goto out;
93 +
94 + *dest = p;
95 + err = 0;
96 +
97 +out:
98 + if (err < 0)
99 reftable_stack_destroy(p);
83 - } else {
84 - *dest = p;
85 - }
100 return err;
101 }
102
@@ -171,6 +185,10 @@ void reftable_stack_destroy(struct reftable_stack *st)
185 {
186 char **names = NULL;
187 int err = 0;
188 +
189 + if (!st)
190 + return;
191 +
192 if (st->merged) {
193 reftable_merged_table_free(st->merged);
194 st->merged = NULL;