reftable/stack: handle allocation failures on reload

Handle allocation failures in `reftable_stack_reload_once()`. 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 dce75e15ffe0030964450c227fac10f1b9614586
1 file changed +25 -9
reftable/stack.c
+25 -9
@@ -214,13 +214,13 @@ void reftable_stack_destroy(struct reftable_stack *st)
214 }
215
216 static struct reftable_reader **stack_copy_readers(struct reftable_stack *st,
217 - int cur_len)
217 + size_t cur_len)
218 {
219 struct reftable_reader **cur = reftable_calloc(cur_len, sizeof(*cur));
220 - int i = 0;
221 - for (i = 0; i < cur_len; i++) {
220 + if (!cur)
221 + return NULL;
222 + for (size_t i = 0; i < cur_len; i++)
223 cur[i] = st->readers[i];
223 - }
224 return cur;
225 }
226
@@ -229,18 +229,30 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
229 int reuse_open)
230 {
231 size_t cur_len = !st->merged ? 0 : st->merged->readers_len;
232 - struct reftable_reader **cur = stack_copy_readers(st, cur_len);
232 + struct reftable_reader **cur;
233 struct reftable_reader **reused = NULL;
234 - size_t reused_len = 0, reused_alloc = 0;
235 - size_t names_len = names_length(names);
236 - struct reftable_reader **new_readers =
237 - reftable_calloc(names_len, sizeof(*new_readers));
234 + struct reftable_reader **new_readers;
235 + size_t reused_len = 0, reused_alloc = 0, names_len;
236 size_t new_readers_len = 0;
237 struct reftable_merged_table *new_merged = NULL;
238 struct strbuf table_path = STRBUF_INIT;
239 int err = 0;
240 size_t i;
241
242 + cur = stack_copy_readers(st, cur_len);
243 + if (!cur) {
244 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
245 + goto done;
246 + }
247 +
248 + names_len = names_length(names);
249 +
250 + new_readers = reftable_calloc(names_len, sizeof(*new_readers));
251 + if (!new_readers) {
252 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
253 + goto done;
254 + }
255 +
256 while (*names) {
257 struct reftable_reader *rd = NULL;
258 const char *name = *names++;
@@ -261,6 +273,10 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
273 * do by bumping their refcount.
274 */
275 REFTABLE_ALLOC_GROW(reused, reused_len + 1, reused_alloc);
276 + if (!reused) {
277 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
278 + goto done;
279 + }
280 reused[reused_len++] = rd;
281 reftable_reader_incref(rd);
282 break;