From: Grzegorz Antoniak Date: Fri, 18 Jan 2019 06:24:17 +0000 (+0100) Subject: RAR5 reader: Removed a memory leak in process_head_file X-Git-Tag: v3.4.0~128^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72f40fab252122a1daa5e3f5484ad2a802dddb70;p=thirdparty%2Flibarchive.git RAR5 reader: Removed a memory leak in process_head_file The process_head_file function was using memset() to clear the archive_entry structure. The problem was that this structure could contain pointers to allocated blocks of memory, and removing those pointers with memset() resulted in a memory leak. Switching it in favor of archive_entry_clear() effectively clears the structure, but also releases any allocated memory blocks. This removes the memory leak. The commit also changes the way a temporary archive_entry instance is being created when skipping a base block after block merge; instead of directly creating a new instance on the stack, a constructor function archive_entry_new() is used to ensure the new archive_entry instance is not in an inconsistent state. This is needed because the fix described in the first half of this commit message depends on the archive_entry instance being in a consistent state due to the call of the archive_entry_clear() function. --- diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index 6d824673e..b5f94e0c0 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -1301,7 +1301,7 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, char name_utf8_buf[2048 * 4]; const uint8_t* p; - memset(entry, 0, sizeof(struct archive_entry)); + archive_entry_clear(entry); /* Do not reset file context if we're switching archives. */ if(!rar->cstate.switch_multivolume) { @@ -1795,8 +1795,14 @@ static int skip_base_block(struct archive_read* a) { int ret; struct rar5* rar = get_context(a); - struct archive_entry entry; - ret = process_base_block(a, &entry); + /* Create a new local archive_entry structure that will be operated on + * by header reader; operations on this archive_entry will be discarded. + */ + struct archive_entry* entry = archive_entry_new(); + ret = process_base_block(a, entry); + + /* Discard operations on this archive_entry structure. */ + archive_entry_free(entry); if(rar->generic.last_header_id == 2 && rar->generic.split_before > 0) return ARCHIVE_OK;