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>
This commit is contained in:
Han-Wen Nienhuys
2022-01-20 15:12:01 +00:00
committed by Junio C Hamano
parent 32d9c0ed1e
commit 24d4d38c0b
3 changed files with 97 additions and 18 deletions

View File

@ -254,6 +254,71 @@ static void test_log_write_read(void)
reader_close(&rd);
}
static void test_log_zlib_corruption(void)
{
struct reftable_write_options opts = {
.block_size = 256,
};
struct reftable_iterator it = { 0 };
struct reftable_reader rd = { 0 };
struct reftable_block_source source = { 0 };
struct strbuf buf = STRBUF_INIT;
struct reftable_writer *w =
reftable_new_writer(&strbuf_add_void, &buf, &opts);
const struct reftable_stats *stats = NULL;
uint8_t hash1[GIT_SHA1_RAWSZ] = { 1 };
uint8_t hash2[GIT_SHA1_RAWSZ] = { 2 };
char message[100] = { 0 };
int err, i, n;
struct reftable_log_record log = {
.refname = "refname",
.value_type = REFTABLE_LOG_UPDATE,
.value = {
.update = {
.new_hash = hash1,
.old_hash = hash2,
.name = "My Name",
.email = "myname@invalid",
.message = message,
},
},
};
for (i = 0; i < sizeof(message) - 1; i++)
message[i] = (uint8_t)(rand() % 64 + ' ');
reftable_writer_set_limits(w, 1, 1);
err = reftable_writer_add_log(w, &log);
EXPECT_ERR(err);
n = reftable_writer_close(w);
EXPECT(n == 0);
stats = writer_stats(w);
EXPECT(stats->log_stats.blocks > 0);
reftable_writer_free(w);
w = NULL;
/* corrupt the data. */
buf.buf[50] ^= 0x99;
block_source_from_strbuf(&source, &buf);
err = init_reader(&rd, &source, "file.log");
EXPECT_ERR(err);
err = reftable_reader_seek_log(&rd, &it, "refname");
EXPECT(err == REFTABLE_ZLIB_ERROR);
reftable_iterator_destroy(&it);
/* cleanup. */
strbuf_release(&buf);
reader_close(&rd);
}
static void test_table_read_write_sequential(void)
{
char **names;
@ -633,6 +698,7 @@ static void test_corrupt_table(void)
int readwrite_test_main(int argc, const char *argv[])
{
RUN_TEST(test_log_zlib_corruption);
RUN_TEST(test_corrupt_table);
RUN_TEST(test_corrupt_table_empty);
RUN_TEST(test_log_write_read);