From: Ngie Cooper Date: Sun, 11 Dec 2016 02:17:01 +0000 (-0800) Subject: - Only allocate `mine` when level == 1 to clarify its lifetime and X-Git-Tag: v3.3.0~91^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2787fd2cd813e579f799f01e1bb5425551938d59;p=thirdparty%2Flibarchive.git - Only allocate `mine` when level == 1 to clarify its lifetime and leak the value less often. - Only free mine->copy_buff when mine != NULL to avoid segfaults if memory_read_close(..) is called with client_data == NULL. This should either address or mitigate the issue reported with Coverity (CID # 1331663) --- diff --git a/libarchive/test/read_open_memory.c b/libarchive/test/read_open_memory.c index f4162eb4b..2bb8d5475 100644 --- a/libarchive/test/read_open_memory.c +++ b/libarchive/test/read_open_memory.c @@ -86,21 +86,7 @@ static int read_open_memory_internal(struct archive *a, const void *buff, size_t size, size_t read_size, int level) { - struct read_memory_data *mine; - - mine = (struct read_memory_data *)malloc(sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - memset(mine, 0, sizeof(*mine)); - mine->start = mine->p = (const unsigned char *)buff; - mine->end = mine->start + size; - mine->read_size = read_size; - mine->copy_buff_offset = 32; - mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; - mine->copy_buff = malloc(mine->copy_buff_size); - memset(mine->copy_buff, 0xA5, mine->copy_buff_size); + struct read_memory_data *mine = NULL; switch (level) { case 3: @@ -109,6 +95,20 @@ read_open_memory_internal(struct archive *a, const void *buff, archive_read_set_open_callback(a, memory_read_open); archive_read_set_skip_callback(a, memory_read_skip); case 1: + mine = malloc(sizeof(*mine)); + if (mine == NULL) { + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); + } + memset(mine, 0, sizeof(*mine)); + mine->start = mine->p = (const unsigned char *)buff; + mine->end = mine->start + size; + mine->read_size = read_size; + mine->copy_buff_offset = 32; + mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; + mine->copy_buff = malloc(mine->copy_buff_size); + memset(mine->copy_buff, 0xA5, mine->copy_buff_size); + archive_read_set_read_callback(a, memory_read); archive_read_set_close_callback(a, memory_read_close); archive_read_set_callback_data(a, mine); @@ -213,7 +213,8 @@ memory_read_close(struct archive *a, void *client_data) { struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ - free(mine->copy_buff); + if (mine != NULL) + free(mine->copy_buff); free(mine); return (ARCHIVE_OK); }