summaryrefslogtreecommitdiffstats
path: root/reftable/block.c
diff options
context:
space:
mode:
authorRené Scharfe <l.s.r@web.de>2024-12-28 10:47:05 +0100
committerJunio C Hamano <gitster@pobox.com>2024-12-28 17:00:44 +0100
commit8db127d43f5b0eff254a851f9c966b7b85d91992 (patch)
tree8c7cd2c2a66573512ade8f4e80f5af8e88fe1e4b /reftable/block.c
parentMerge https://github.com/j6t/git-gui (diff)
downloadgit-8db127d43f5b0eff254a851f9c966b7b85d91992.tar.xz
git-8db127d43f5b0eff254a851f9c966b7b85d91992.zip
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/block.c')
-rw-r--r--reftable/block.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/reftable/block.c b/reftable/block.c
index 0198078485..9858bbc7c5 100644
--- a/reftable/block.c
+++ b/reftable/block.c
@@ -53,7 +53,8 @@ static int block_writer_register_restart(struct block_writer *w, int n,
if (2 + 3 * rlen + n > w->block_size - w->next)
return -1;
if (is_restart) {
- REFTABLE_ALLOC_GROW(w->restarts, w->restart_len + 1, w->restart_cap);
+ REFTABLE_ALLOC_GROW_OR_NULL(w->restarts, w->restart_len + 1,
+ w->restart_cap);
if (!w->restarts)
return REFTABLE_OUT_OF_MEMORY_ERROR;
w->restarts[w->restart_len++] = w->next;
@@ -176,7 +177,8 @@ int block_writer_finish(struct block_writer *w)
* is guaranteed to return `Z_STREAM_END`.
*/
compressed_len = deflateBound(w->zstream, src_len);
- REFTABLE_ALLOC_GROW(w->compressed, compressed_len, w->compressed_cap);
+ REFTABLE_ALLOC_GROW_OR_NULL(w->compressed, compressed_len,
+ w->compressed_cap);
if (!w->compressed) {
ret = REFTABLE_OUT_OF_MEMORY_ERROR;
return ret;
@@ -235,8 +237,8 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
uLong src_len = block->len - block_header_skip;
/* Log blocks specify the *uncompressed* size in their header. */
- REFTABLE_ALLOC_GROW(br->uncompressed_data, sz,
- br->uncompressed_cap);
+ REFTABLE_ALLOC_GROW_OR_NULL(br->uncompressed_data, sz,
+ br->uncompressed_cap);
if (!br->uncompressed_data) {
err = REFTABLE_OUT_OF_MEMORY_ERROR;
goto done;