Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan-Wen Nienhuys <hanwen@google.com>2022-01-20 18:12:01 +0300
committerJunio C Hamano <gitster@pobox.com>2022-01-20 22:31:52 +0300
commit24d4d38c0b32fd4eb075af89d7b744c5647db5c2 (patch)
treecc34419ff31ed2e2ded0670ae2df522cf5fa18c8 /reftable/block.c
parent32d9c0ed1e9d7ebb539dcc8ec573c025a49b9936 (diff)
reftable: fix resource leak in block.c error path
Add test coverage for corrupt zlib data. Fix memory leaks demonstrated by unittest. This problem was discovered by a Coverity scan. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'reftable/block.c')
-rw-r--r--reftable/block.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/reftable/block.c b/reftable/block.c
index 855e3f5c94..6c8e870520 100644
--- a/reftable/block.c
+++ b/reftable/block.c
@@ -188,13 +188,16 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
uint32_t full_block_size = table_block_size;
uint8_t typ = block->data[header_off];
uint32_t sz = get_be24(block->data + header_off + 1);
-
+ int err = 0;
uint16_t restart_count = 0;
uint32_t restart_start = 0;
uint8_t *restart_bytes = NULL;
+ uint8_t *uncompressed = NULL;
- if (!reftable_is_block_type(typ))
- return REFTABLE_FORMAT_ERROR;
+ if (!reftable_is_block_type(typ)) {
+ err = REFTABLE_FORMAT_ERROR;
+ goto done;
+ }
if (typ == BLOCK_TYPE_LOG) {
int block_header_skip = 4 + header_off;
@@ -203,7 +206,7 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
uLongf src_len = block->len - block_header_skip;
/* Log blocks specify the *uncompressed* size in their header.
*/
- uint8_t *uncompressed = reftable_malloc(sz);
+ uncompressed = reftable_malloc(sz);
/* Copy over the block header verbatim. It's not compressed. */
memcpy(uncompressed, block->data, block_header_skip);
@@ -212,16 +215,19 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
if (Z_OK !=
uncompress2(uncompressed + block_header_skip, &dst_len,
block->data + block_header_skip, &src_len)) {
- reftable_free(uncompressed);
- return REFTABLE_ZLIB_ERROR;
+ err = REFTABLE_ZLIB_ERROR;
+ goto done;
}
- if (dst_len + block_header_skip != sz)
- return REFTABLE_FORMAT_ERROR;
+ if (dst_len + block_header_skip != sz) {
+ err = REFTABLE_FORMAT_ERROR;
+ goto done;
+ }
/* We're done with the input data. */
reftable_block_done(block);
block->data = uncompressed;
+ uncompressed = NULL;
block->len = sz;
block->source = malloc_block_source();
full_block_size = src_len + block_header_skip;
@@ -251,7 +257,9 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
br->restart_count = restart_count;
br->restart_bytes = restart_bytes;
- return 0;
+done:
+ reftable_free(uncompressed);
+ return err;
}
static uint32_t block_reader_restart_offset(struct block_reader *br, int i)