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
@ -246,8 +246,8 @@ static int reftable_ref_record_copy_from(void *rec, const void *src_rec,
|
||||
if (src->refname) {
|
||||
size_t refname_len = strlen(src->refname);
|
||||
|
||||
REFTABLE_ALLOC_GROW(ref->refname, refname_len + 1,
|
||||
ref->refname_cap);
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(ref->refname, refname_len + 1,
|
||||
ref->refname_cap);
|
||||
if (!ref->refname) {
|
||||
err = REFTABLE_OUT_OF_MEMORY_ERROR;
|
||||
goto out;
|
||||
@ -385,7 +385,7 @@ static int reftable_ref_record_decode(void *rec, struct reftable_buf key,
|
||||
SWAP(r->refname, refname);
|
||||
SWAP(r->refname_cap, refname_cap);
|
||||
|
||||
REFTABLE_ALLOC_GROW(r->refname, key.len + 1, r->refname_cap);
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len + 1, r->refname_cap);
|
||||
if (!r->refname) {
|
||||
err = REFTABLE_OUT_OF_MEMORY_ERROR;
|
||||
goto done;
|
||||
@ -839,7 +839,7 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key,
|
||||
if (key.len <= 9 || key.buf[key.len - 9] != 0)
|
||||
return REFTABLE_FORMAT_ERROR;
|
||||
|
||||
REFTABLE_ALLOC_GROW(r->refname, key.len - 8, r->refname_cap);
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len - 8, r->refname_cap);
|
||||
if (!r->refname) {
|
||||
err = REFTABLE_OUT_OF_MEMORY_ERROR;
|
||||
goto done;
|
||||
@ -947,8 +947,8 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key,
|
||||
}
|
||||
string_view_consume(&in, n);
|
||||
|
||||
REFTABLE_ALLOC_GROW(r->value.update.message, scratch->len + 1,
|
||||
r->value.update.message_cap);
|
||||
REFTABLE_ALLOC_GROW_OR_NULL(r->value.update.message, scratch->len + 1,
|
||||
r->value.update.message_cap);
|
||||
if (!r->value.update.message) {
|
||||
err = REFTABLE_OUT_OF_MEMORY_ERROR;
|
||||
goto done;
|
||||
|
Reference in New Issue
Block a user