diff --git a/libretro-common/file/archive_file.c b/libretro-common/file/archive_file.c index b2f35518f4..675145432a 100644 --- a/libretro-common/file/archive_file.c +++ b/libretro-common/file/archive_file.c @@ -348,11 +348,20 @@ end: if (handle->backend) { if (handle->backend->stream_free) - handle->backend->stream_free(handle->stream); - } + { +#ifdef HAVE_7ZIP + if (handle->backend != &sevenzip_backend) + { + handle->backend->stream_free(handle->stream); - if (handle->data) - free(handle->data); + if (handle->data) + free(handle->data); + } +#else + handle->backend->stream_free(handle->stream); +#endif + } + } } return ret; @@ -406,7 +415,9 @@ int file_archive_parse_file_iterate( valid_exts, userdata, file_cb); if (ret != 1) + { state->type = ARCHIVE_TRANSFER_DEINIT; + } if (ret == -1) state->type = ARCHIVE_TRANSFER_DEINIT_ERROR; diff --git a/libretro-common/file/archive_file_7z.c b/libretro-common/file/archive_file_7z.c index 0f00c0723d..86e03b7d11 100644 --- a/libretro-common/file/archive_file_7z.c +++ b/libretro-common/file/archive_file_7z.c @@ -70,7 +70,9 @@ static void *sevenzip_stream_alloc_impl(void *p, size_t size) static void sevenzip_stream_free_impl(void *p, void *address) { (void)p; - free(address); + + if (address) + free(address); } static void *sevenzip_stream_alloc_tmp_impl(void *p, size_t size) @@ -450,6 +452,8 @@ static int sevenzip_parse_file_iterate_step_internal( *csize = (uint32_t)compressed_size; } } + else + return 0; *payback = 1; diff --git a/libretro-common/include/file/archive_file.h b/libretro-common/include/file/archive_file.h index 6cc7d4725b..3861f6ac89 100644 --- a/libretro-common/include/file/archive_file.h +++ b/libretro-common/include/file/archive_file.h @@ -39,6 +39,8 @@ RETRO_BEGIN_DECLS +struct archive_extract_userdata; + enum file_archive_transfer_type { ARCHIVE_TRANSFER_NONE = 0, @@ -96,6 +98,7 @@ typedef struct char *callback_error; file_archive_transfer_t archive; + struct archive_extract_userdata *userdata; } decompress_state_t; struct archive_extract_userdata diff --git a/tasks/task_decompress.c b/tasks/task_decompress.c index 2ee85efa38..80b5ddf9db 100644 --- a/tasks/task_decompress.c +++ b/tasks/task_decompress.c @@ -97,7 +97,7 @@ static int file_decompressed(const char *name, const char *valid_exts, path[0] = '\0'; /* Ignore directories. */ - if ( name[strlen(name) - 1] == '/' || + if ( name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\') goto next_file; @@ -152,6 +152,8 @@ static void task_decompress_handler_finished(retro_task_t *task, free(dec->subdir); if (dec->valid_ext) free(dec->valid_ext); + if (dec->userdata) + free(dec->userdata); free(dec->target_dir); free(dec); } @@ -160,18 +162,17 @@ static void task_decompress_handler(retro_task_t *task) { int ret; bool retdec = false; - struct archive_extract_userdata userdata = {{0}}; decompress_state_t *dec = (decompress_state_t*) task->state; - userdata.dec = dec; - strlcpy(userdata.archive_path, - dec->source_file, sizeof(userdata.archive_path)); + dec->userdata->dec = dec; + strlcpy(dec->userdata->archive_path, + dec->source_file, sizeof(dec->userdata->archive_path)); ret = file_archive_parse_file_iterate( &dec->archive, &retdec, dec->source_file, - dec->valid_ext, file_decompressed, &userdata); + dec->valid_ext, file_decompressed, dec->userdata); task_set_progress(task, file_archive_parse_file_progress(&dec->archive)); @@ -189,16 +190,15 @@ static void task_decompress_handler_target_file(retro_task_t *task) { bool retdec; int ret; - struct archive_extract_userdata userdata = {{0}}; decompress_state_t *dec = (decompress_state_t*) task->state; - strlcpy(userdata.archive_path, - dec->source_file, sizeof(userdata.archive_path)); + strlcpy(dec->userdata->archive_path, + dec->source_file, sizeof(dec->userdata->archive_path)); ret = file_archive_parse_file_iterate(&dec->archive, &retdec, dec->source_file, - dec->valid_ext, file_decompressed_target_file, &userdata); + dec->valid_ext, file_decompressed_target_file, dec->userdata); task_set_progress(task, file_archive_parse_file_progress(&dec->archive)); @@ -217,17 +217,16 @@ static void task_decompress_handler_subdir(retro_task_t *task) int ret; bool retdec; decompress_state_t *dec = (decompress_state_t*)task->state; - struct archive_extract_userdata userdata = {{0}}; - userdata.dec = dec; - strlcpy(userdata.archive_path, + dec->userdata->dec = dec; + strlcpy(dec->userdata->archive_path, dec->source_file, - sizeof(userdata.archive_path)); + sizeof(dec->userdata->archive_path)); ret = file_archive_parse_file_iterate( &dec->archive, &retdec, dec->source_file, - dec->valid_ext, file_decompressed_subdir, &userdata); + dec->valid_ext, file_decompressed_subdir, dec->userdata); task_set_progress(task, file_archive_parse_file_progress(&dec->archive)); @@ -332,6 +331,7 @@ bool task_push_decompress( s->valid_ext = valid_ext ? strdup(valid_ext) : NULL; s->archive.type = ARCHIVE_TRANSFER_INIT; + s->userdata = (struct archive_extract_userdata*)calloc(1, sizeof(*s->userdata)); t = (retro_task_t*)calloc(1, sizeof(*t)); @@ -367,6 +367,10 @@ bool task_push_decompress( error: if (s) + { + if (s->userdata) + free(s->userdata); free(s); + } return false; }