reftable/stack: fix zero-sized allocation when there are no readers

Similar as the preceding commit, we may try to do a zero-sized allocation when reloading a reftable stack that ain't got any tables. It is implementation-defined whether malloc(3p) returns a NULL pointer in that case or a zero-sized object. In case it does return a NULL pointer though it causes us to think we have run into an out-of-memory situation, and thus we return an error. Fix this by only allocating arrays when they have at least one entry. Reported-by: Randall S. Becker <rsbecker@nexbridge.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Dec 22, 2024 at 08:24 UTC 2d3cb4b4b5401e2fd5a40600277f424032fc72f0
1 file changed +14 -10
reftable/stack.c
+14 -10
@@ -254,9 +254,9 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
254 int reuse_open)
255 {
256 size_t cur_len = !st->merged ? 0 : st->merged->readers_len;
257 - struct reftable_reader **cur;
257 + struct reftable_reader **cur = NULL;
258 struct reftable_reader **reused = NULL;
259 - struct reftable_reader **new_readers;
259 + struct reftable_reader **new_readers = NULL;
260 size_t reused_len = 0, reused_alloc = 0, names_len;
261 size_t new_readers_len = 0;
262 struct reftable_merged_table *new_merged = NULL;
@@ -264,18 +264,22 @@ static int reftable_stack_reload_once(struct reftable_stack *st,
264 int err = 0;
265 size_t i;
266
267 - cur = stack_copy_readers(st, cur_len);
268 - if (!cur) {
269 - err = REFTABLE_OUT_OF_MEMORY_ERROR;
270 - goto done;
267 + if (cur_len) {
268 + cur = stack_copy_readers(st, cur_len);
269 + if (!cur) {
270 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
271 + goto done;
272 + }
273 }
274
275 names_len = names_length(names);
276
275 - new_readers = reftable_calloc(names_len, sizeof(*new_readers));
276 - if (!new_readers) {
277 - err = REFTABLE_OUT_OF_MEMORY_ERROR;
278 - goto done;
277 + if (names_len) {
278 + new_readers = reftable_calloc(names_len, sizeof(*new_readers));
279 + if (!new_readers) {
280 + err = REFTABLE_OUT_OF_MEMORY_ERROR;
281 + goto done;
282 + }
283 }
284
285 while (*names) {