diff options
| author | René Scharfe <l.s.r@web.de> | 2024-12-28 10:47:05 +0100 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-12-28 08:00:44 -0800 |
| commit | 8db127d43f5b0eff254a851f9c966b7b85d91992 (patch) | |
| tree | 8c7cd2c2a66573512ade8f4e80f5af8e88fe1e4b /reftable/basics.h | |
| parent | 76cf4f61c87855ebf0784b88aaf737d6b09f504b (diff) | |
| download | git-8db127d43f5b0eff254a851f9c966b7b85d91992.tar.gz | |
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>
Diffstat (limited to 'reftable/basics.h')
| -rw-r--r-- | reftable/basics.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/reftable/basics.h b/reftable/basics.h index 36beda2c25..259f4c274c 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -129,6 +129,16 @@ char *reftable_strdup(const char *str); REFTABLE_REALLOC_ARRAY(x, alloc); \ } \ } while (0) + +#define REFTABLE_ALLOC_GROW_OR_NULL(x, nr, alloc) do { \ + void *reftable_alloc_grow_or_null_orig_ptr = (x); \ + REFTABLE_ALLOC_GROW((x), (nr), (alloc)); \ + if (!(x)) { \ + reftable_free(reftable_alloc_grow_or_null_orig_ptr); \ + alloc = 0; \ + } \ +} while (0) + #define REFTABLE_FREE_AND_NULL(p) do { reftable_free(p); (p) = NULL; } while (0) #ifndef REFTABLE_ALLOW_BANNED_ALLOCATORS |
