reftable: avoid leaks on realloc error
When realloc(3) fails, it returns NULL and keeps the original allocation intact. REFTABLE_ALLOC_GROW overwrites both the original pointer and the allocation count variable in that case, simultaneously leaking the original allocation and misrepresenting the number of storable items. parse_names() and reftable_buf_add() avoid leaking by restoring the original pointer value on failure, but all other callers seem to be OK with losing the old allocation. Add a new variant of the macro, REFTABLE_ALLOC_GROW_OR_NULL, which plugs the leak and zeros the allocation counter. Use it for those callers. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
76cf4f61c8
commit
8db127d43f
@ -20,6 +20,11 @@ static int integer_needle_lesseq(size_t i, void *_args)
|
||||
return args->needle <= args->haystack[i];
|
||||
}
|
||||
|
||||
static void *realloc_stub(void *p UNUSED, size_t size UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
|
||||
{
|
||||
if_test ("binary search with binsearch works") {
|
||||
@ -141,5 +146,30 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED)
|
||||
check_int(in, ==, out);
|
||||
}
|
||||
|
||||
if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") {
|
||||
int *arr = NULL;
|
||||
size_t alloc = 0, old_alloc;
|
||||
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc);
|
||||
check(arr != NULL);
|
||||
check_uint(alloc, >=, 1);
|
||||
arr[0] = 42;
|
||||
|
||||
old_alloc = alloc;
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
|
||||
check(arr != NULL);
|
||||
check_uint(alloc, >, old_alloc);
|
||||
arr[alloc - 1] = 42;
|
||||
|
||||
old_alloc = alloc;
|
||||
reftable_set_alloc(malloc, realloc_stub, free);
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc);
|
||||
check(arr == NULL);
|
||||
check_uint(alloc, ==, 0);
|
||||
reftable_set_alloc(malloc, realloc, free);
|
||||
|
||||
reftable_free(arr);
|
||||
}
|
||||
|
||||
return test_done();
|
||||
}
|
||||
|
Reference in New Issue
Block a user