mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-24 20:26:52 +00:00
fix more memory corruption
This commit is contained in:
parent
dc4760f5a6
commit
a7ffead8f6
@ -182,13 +182,11 @@ static int file_archive_get_file_list_cb(
|
||||
uint32_t csize,
|
||||
uint32_t size,
|
||||
uint32_t checksum,
|
||||
void *userdata)
|
||||
struct archive_extract_userdata *userdata)
|
||||
{
|
||||
union string_list_elem_attr attr;
|
||||
struct string_list *ext_list = NULL;
|
||||
const char *file_ext = NULL;
|
||||
struct archive_extract_userdata *data =
|
||||
(struct archive_extract_userdata*)userdata;
|
||||
size_t pathLen = strlen(path);
|
||||
|
||||
(void)cdata;
|
||||
@ -224,7 +222,7 @@ static int file_archive_get_file_list_cb(
|
||||
string_list_free(ext_list);
|
||||
}
|
||||
|
||||
return string_list_append(data->list, path, attr);
|
||||
return string_list_append(userdata->list, path, attr);
|
||||
|
||||
error:
|
||||
string_list_free(ext_list);
|
||||
@ -234,28 +232,26 @@ error:
|
||||
static int file_archive_extract_cb(const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata,
|
||||
unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t checksum, void *userdata)
|
||||
uint32_t checksum, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
const char *ext = path_get_extension(name);
|
||||
struct archive_extract_userdata *data = (struct archive_extract_userdata*)
|
||||
userdata;
|
||||
|
||||
/* Extract first file that matches our list. */
|
||||
if (ext && string_list_find_elem(data->ext, ext))
|
||||
if (ext && string_list_find_elem(userdata->ext, ext))
|
||||
{
|
||||
char new_path[PATH_MAX_LENGTH] = {0};
|
||||
|
||||
if (data->extraction_directory)
|
||||
fill_pathname_join(new_path, data->extraction_directory,
|
||||
if (userdata->extraction_directory)
|
||||
fill_pathname_join(new_path, userdata->extraction_directory,
|
||||
path_basename(name), sizeof(new_path));
|
||||
else
|
||||
fill_pathname_resolve_relative(new_path, data->archive_path,
|
||||
fill_pathname_resolve_relative(new_path, userdata->archive_path,
|
||||
path_basename(name), sizeof(new_path));
|
||||
|
||||
data->first_extracted_file_path = strdup(new_path);
|
||||
data->found_file = file_archive_perform_mode(new_path,
|
||||
userdata->first_extracted_file_path = strdup(new_path);
|
||||
userdata->found_file = file_archive_perform_mode(new_path,
|
||||
valid_exts, cdata, cmode, csize, size,
|
||||
0, data);
|
||||
0, userdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -361,7 +357,7 @@ int file_archive_parse_file_iterate(
|
||||
const char *file,
|
||||
const char *valid_exts,
|
||||
file_archive_file_cb file_cb,
|
||||
void *userdata)
|
||||
struct archive_extract_userdata *userdata)
|
||||
{
|
||||
if (!state)
|
||||
return -1;
|
||||
@ -373,10 +369,8 @@ int file_archive_parse_file_iterate(
|
||||
case ARCHIVE_TRANSFER_INIT:
|
||||
if (file_archive_parse_file_init(state, file) == 0)
|
||||
{
|
||||
struct archive_extract_userdata *data =
|
||||
(struct archive_extract_userdata*)userdata;
|
||||
if (data)
|
||||
data->context = state->stream;
|
||||
if (userdata)
|
||||
userdata->context = state->stream;
|
||||
state->type = ARCHIVE_TRANSFER_ITERATE;
|
||||
}
|
||||
else
|
||||
@ -384,7 +378,7 @@ int file_archive_parse_file_iterate(
|
||||
break;
|
||||
case ARCHIVE_TRANSFER_ITERATE:
|
||||
{
|
||||
const struct file_archive_file_backend *backend =
|
||||
const struct file_archive_file_backend *backend =
|
||||
file_archive_get_file_backend(file);
|
||||
|
||||
if (backend)
|
||||
@ -413,8 +407,6 @@ int file_archive_parse_file_iterate(
|
||||
}
|
||||
if (state->stream && state->backend)
|
||||
{
|
||||
struct archive_extract_userdata *data =
|
||||
(struct archive_extract_userdata*)userdata;
|
||||
state->backend->stream_free(state->stream);
|
||||
|
||||
if (state->stream)
|
||||
@ -422,8 +414,8 @@ int file_archive_parse_file_iterate(
|
||||
|
||||
state->stream = NULL;
|
||||
|
||||
if (data)
|
||||
data->context = NULL;
|
||||
if (userdata)
|
||||
userdata->context = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -449,7 +441,7 @@ int file_archive_parse_file_iterate(
|
||||
* Returns: true (1) on success, otherwise false (0).
|
||||
**/
|
||||
static bool file_archive_parse_file(const char *file, const char *valid_exts,
|
||||
file_archive_file_cb file_cb, void *userdata)
|
||||
file_archive_file_cb file_cb, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
file_archive_transfer_t state = {0};
|
||||
bool returnerr = true;
|
||||
@ -572,7 +564,7 @@ error:
|
||||
|
||||
bool file_archive_perform_mode(const char *path, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
switch (cmode)
|
||||
{
|
||||
@ -585,10 +577,9 @@ bool file_archive_perform_mode(const char *path, const char *valid_exts,
|
||||
{
|
||||
int ret = 0;
|
||||
file_archive_file_handle_t handle = {0};
|
||||
struct archive_extract_userdata *data = (struct archive_extract_userdata*)userdata;
|
||||
|
||||
handle.backend = file_archive_get_file_backend(data->archive_path);
|
||||
handle.stream = data->context;
|
||||
handle.backend = file_archive_get_file_backend(userdata->archive_path);
|
||||
handle.stream = userdata->context;
|
||||
|
||||
if (!handle.backend->stream_decompress_data_to_file_init(&handle,
|
||||
cdata, csize, size))
|
||||
|
@ -344,7 +344,7 @@ static int sevenzip_parse_file_iterate_step_internal(
|
||||
}
|
||||
|
||||
static int sevenzip_parse_file_iterate_step(file_archive_transfer_t *state,
|
||||
const char *valid_exts, void *userdata, file_archive_file_cb file_cb)
|
||||
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
|
||||
{
|
||||
const uint8_t *cdata = NULL;
|
||||
uint32_t checksum = 0;
|
||||
|
@ -208,15 +208,6 @@ static uint32_t zlib_stream_crc32_calculate(uint32_t crc,
|
||||
return encoding_crc32(crc, data, length);
|
||||
}
|
||||
|
||||
struct decomp_state
|
||||
{
|
||||
char *opt_file;
|
||||
char *needle;
|
||||
void **buf;
|
||||
size_t size;
|
||||
bool found;
|
||||
};
|
||||
|
||||
static bool zip_file_decompressed_handle(
|
||||
file_archive_file_handle_t *handle,
|
||||
const uint8_t *cdata, uint32_t csize,
|
||||
@ -270,10 +261,8 @@ static int zip_file_decompressed(
|
||||
const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode,
|
||||
uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
struct decomp_state *st = (struct decomp_state*)userdata;
|
||||
|
||||
/* Ignore directories. */
|
||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||
return 1;
|
||||
@ -282,17 +271,17 @@ static int zip_file_decompressed(
|
||||
RARCH_LOG("[deflate] Path: %s, CRC32: 0x%x\n", name, crc32);
|
||||
#endif
|
||||
|
||||
if (strstr(name, st->needle))
|
||||
if (strstr(name, userdata->decomp_state.needle))
|
||||
{
|
||||
bool goto_error = false;
|
||||
file_archive_file_handle_t handle = {0};
|
||||
|
||||
st->found = true;
|
||||
userdata->decomp_state.found = true;
|
||||
|
||||
if (zip_file_decompressed_handle(&handle,
|
||||
cdata, csize, size, crc32))
|
||||
{
|
||||
if (st->opt_file != 0)
|
||||
if (userdata->decomp_state.opt_file != 0)
|
||||
{
|
||||
/* Called in case core has need_fullpath enabled. */
|
||||
char *buf = (char*)malloc(size);
|
||||
@ -301,26 +290,26 @@ static int zip_file_decompressed(
|
||||
{
|
||||
/*RARCH_LOG("%s: %s\n",
|
||||
msg_hash_to_str(MSG_EXTRACTING_FILE),
|
||||
st->opt_file);*/
|
||||
userdata->decomp_state.opt_file);*/
|
||||
memcpy(buf, handle.data, size);
|
||||
|
||||
if (!filestream_write_file(st->opt_file, buf, size))
|
||||
if (!filestream_write_file(userdata->decomp_state.opt_file, buf, size))
|
||||
goto_error = true;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
st->size = 0;
|
||||
userdata->decomp_state.size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Called in case core has need_fullpath disabled.
|
||||
* Will copy decompressed content directly into
|
||||
* RetroArch's ROM buffer. */
|
||||
*st->buf = malloc(size);
|
||||
memcpy(*st->buf, handle.data, size);
|
||||
*userdata->decomp_state.buf = malloc(size);
|
||||
memcpy(*userdata->decomp_state.buf, handle.data, size);
|
||||
|
||||
st->size = size;
|
||||
userdata->decomp_state.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,41 +329,41 @@ static int zip_file_read(
|
||||
const char *optional_outfile)
|
||||
{
|
||||
file_archive_transfer_t zlib;
|
||||
struct decomp_state st;
|
||||
bool returnerr = true;
|
||||
int ret = 0;
|
||||
struct archive_extract_userdata userdata = {0};
|
||||
|
||||
zlib.type = ARCHIVE_TRANSFER_INIT;
|
||||
|
||||
st.needle = NULL;
|
||||
st.opt_file = NULL;
|
||||
st.found = false;
|
||||
st.buf = buf;
|
||||
userdata.decomp_state.needle = NULL;
|
||||
userdata.decomp_state.opt_file = NULL;
|
||||
userdata.decomp_state.found = false;
|
||||
userdata.decomp_state.buf = buf;
|
||||
|
||||
if (needle)
|
||||
st.needle = strdup(needle);
|
||||
userdata.decomp_state.needle = strdup(needle);
|
||||
if (optional_outfile)
|
||||
st.opt_file = strdup(optional_outfile);
|
||||
userdata.decomp_state.opt_file = strdup(optional_outfile);
|
||||
|
||||
do
|
||||
{
|
||||
ret = file_archive_parse_file_iterate(&zlib, &returnerr, path,
|
||||
"", zip_file_decompressed, &st);
|
||||
"", zip_file_decompressed, &userdata);
|
||||
if (!returnerr)
|
||||
break;
|
||||
}while(ret == 0 && !st.found);
|
||||
}while(ret == 0 && !userdata.decomp_state.found);
|
||||
|
||||
file_archive_parse_file_iterate_stop(&zlib);
|
||||
|
||||
if (st.opt_file)
|
||||
free(st.opt_file);
|
||||
if (st.needle)
|
||||
free(st.needle);
|
||||
if (userdata.decomp_state.opt_file)
|
||||
free(userdata.decomp_state.opt_file);
|
||||
if (userdata.decomp_state.needle)
|
||||
free(userdata.decomp_state.needle);
|
||||
|
||||
if (!st.found)
|
||||
if (!userdata.decomp_state.found)
|
||||
return -1;
|
||||
|
||||
return st.size;
|
||||
return userdata.decomp_state.size;
|
||||
}
|
||||
|
||||
static int zip_parse_file_init(file_archive_transfer_t *state,
|
||||
@ -442,7 +431,7 @@ static int zip_parse_file_iterate_step_internal(
|
||||
}
|
||||
|
||||
static int zip_parse_file_iterate_step(file_archive_transfer_t *state,
|
||||
const char *valid_exts, void *userdata, file_archive_file_cb file_cb)
|
||||
const char *valid_exts, struct archive_extract_userdata *userdata, file_archive_file_cb file_cb)
|
||||
{
|
||||
const uint8_t *cdata = NULL;
|
||||
uint32_t checksum = 0;
|
||||
|
@ -25,9 +25,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
enum file_archive_transfer_type
|
||||
{
|
||||
ARCHIVE_TRANSFER_NONE = 0,
|
||||
@ -63,6 +64,28 @@ enum file_archive_compression_mode
|
||||
ARCHIVE_MODE_COMPRESSED = 8
|
||||
};
|
||||
|
||||
struct decomp_state_t
|
||||
{
|
||||
char *opt_file;
|
||||
char *needle;
|
||||
void **buf;
|
||||
size_t size;
|
||||
bool found;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *source_file;
|
||||
char *subdir;
|
||||
char *target_dir;
|
||||
char *target_file;
|
||||
char *valid_ext;
|
||||
|
||||
char *callback_error;
|
||||
|
||||
file_archive_transfer_t archive;
|
||||
} decompress_state_t;
|
||||
|
||||
struct archive_extract_userdata
|
||||
{
|
||||
char *archive_path;
|
||||
@ -73,12 +96,16 @@ struct archive_extract_userdata
|
||||
struct string_list *list;
|
||||
bool found_file;
|
||||
void *context;
|
||||
char archive_name[PATH_MAX_LENGTH];
|
||||
uint32_t crc;
|
||||
struct decomp_state_t decomp_state;
|
||||
decompress_state_t dec;
|
||||
};
|
||||
|
||||
/* Returns true when parsing should continue. False to stop. */
|
||||
typedef int (*file_archive_file_cb)(const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata);
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata);
|
||||
|
||||
struct file_archive_file_backend
|
||||
{
|
||||
@ -106,7 +133,7 @@ struct file_archive_file_backend
|
||||
int (*archive_parse_file_iterate_step)(
|
||||
file_archive_transfer_t *state,
|
||||
const char *valid_exts,
|
||||
void *userdata,
|
||||
struct archive_extract_userdata *userdata,
|
||||
file_archive_file_cb file_cb);
|
||||
const char *ident;
|
||||
};
|
||||
@ -117,7 +144,7 @@ int file_archive_parse_file_iterate(
|
||||
const char *file,
|
||||
const char *valid_exts,
|
||||
file_archive_file_cb file_cb,
|
||||
void *userdata);
|
||||
struct archive_extract_userdata *userdata);
|
||||
|
||||
void file_archive_parse_file_iterate_stop(file_archive_transfer_t *state);
|
||||
|
||||
@ -151,7 +178,7 @@ struct string_list* file_archive_get_file_list(const char *path, const char *val
|
||||
|
||||
bool file_archive_perform_mode(const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata);
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata);
|
||||
|
||||
void file_archive_deflate_init(void *data, int level);
|
||||
|
||||
|
@ -66,13 +66,9 @@ typedef struct db_handle
|
||||
#ifdef HAVE_COMPRESSION
|
||||
static int archive_compare_crc32(const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
database_state_handle_t *db_state = (database_state_handle_t*)userdata;
|
||||
|
||||
db_state->crc = crc32;
|
||||
|
||||
strlcpy(db_state->archive_name, name, sizeof(db_state->archive_name));
|
||||
userdata->crc = crc32;
|
||||
|
||||
#if 0
|
||||
RARCH_LOG("Going to compare CRC 0x%x for %s\n", crc32, name);
|
||||
@ -418,6 +414,10 @@ static int task_database_iterate_playlist_archive(
|
||||
return task_database_iterate_crc_lookup(
|
||||
db_state, db, db_state->archive_name);
|
||||
|
||||
strlcpy(userdata.archive_name, db_state->archive_name, sizeof(userdata.archive_name));
|
||||
|
||||
userdata.crc = db_state->crc;
|
||||
|
||||
if (file_archive_parse_file_iterate(&db->state,
|
||||
&returnerr, name, NULL, archive_compare_crc32,
|
||||
&userdata))
|
||||
|
@ -25,24 +25,11 @@
|
||||
#include "../verbosity.h"
|
||||
#include "../msg_hash.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *source_file;
|
||||
char *subdir;
|
||||
char *target_dir;
|
||||
char *target_file;
|
||||
char *valid_ext;
|
||||
|
||||
char *callback_error;
|
||||
|
||||
file_archive_transfer_t archive;
|
||||
} decompress_state_t;
|
||||
|
||||
static int file_decompressed_target_file(const char *name,
|
||||
const char *valid_exts,
|
||||
const uint8_t *cdata,
|
||||
unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
/* TODO/FIXME */
|
||||
return 0;
|
||||
@ -52,22 +39,21 @@ static int file_decompressed_subdir(const char *name,
|
||||
const char *valid_exts,
|
||||
const uint8_t *cdata,
|
||||
unsigned cmode, uint32_t csize,uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
char path_dir[PATH_MAX_LENGTH] = {0};
|
||||
char path[PATH_MAX_LENGTH] = {0};
|
||||
decompress_state_t *dec = (decompress_state_t*)userdata;
|
||||
|
||||
/* Ignore directories. */
|
||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||
goto next_file;
|
||||
|
||||
if (strstr(name, dec->subdir) != name)
|
||||
if (strstr(name, userdata->dec.subdir) != name)
|
||||
return 1;
|
||||
|
||||
name += strlen(dec->subdir) + 1;
|
||||
name += strlen(userdata->dec.subdir) + 1;
|
||||
|
||||
fill_pathname_join(path, dec->target_dir, name, sizeof(path));
|
||||
fill_pathname_join(path, userdata->dec.target_dir, name, sizeof(path));
|
||||
fill_pathname_basedir(path_dir, path, sizeof(path_dir));
|
||||
|
||||
/* Make directory */
|
||||
@ -84,8 +70,8 @@ next_file:
|
||||
return 1;
|
||||
|
||||
error:
|
||||
dec->callback_error = (char*)malloc(PATH_MAX_LENGTH);
|
||||
snprintf(dec->callback_error,
|
||||
userdata->dec.callback_error = (char*)malloc(PATH_MAX_LENGTH);
|
||||
snprintf(userdata->dec.callback_error,
|
||||
PATH_MAX_LENGTH, "Failed to deflate %s.\n", path);
|
||||
|
||||
return 0;
|
||||
@ -93,10 +79,10 @@ error:
|
||||
|
||||
static int file_decompressed(const char *name, const char *valid_exts,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
uint32_t crc32, struct archive_extract_userdata *userdata)
|
||||
{
|
||||
char path[PATH_MAX_LENGTH] = {0};
|
||||
decompress_state_t *dec = (decompress_state_t*)userdata;
|
||||
decompress_state_t *dec = &userdata->dec;
|
||||
|
||||
/* Ignore directories. */
|
||||
if (name[strlen(name) - 1] == '/' || name[strlen(name) - 1] == '\\')
|
||||
@ -180,9 +166,10 @@ static void task_decompress_handler_target_file(retro_task_t *task)
|
||||
{
|
||||
bool retdec;
|
||||
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||
struct archive_extract_userdata userdata = {0};
|
||||
int ret = file_archive_parse_file_iterate(&dec->archive,
|
||||
&retdec, dec->source_file,
|
||||
dec->valid_ext, file_decompressed_target_file, dec);
|
||||
dec->valid_ext, file_decompressed_target_file, &userdata);
|
||||
|
||||
task->progress = file_archive_parse_file_progress(&dec->archive);
|
||||
|
||||
@ -201,6 +188,8 @@ static void task_decompress_handler_subdir(retro_task_t *task)
|
||||
decompress_state_t *dec = (decompress_state_t*)task->state;
|
||||
struct archive_extract_userdata userdata = {0};
|
||||
|
||||
userdata.dec = *dec;
|
||||
|
||||
int ret = file_archive_parse_file_iterate(&dec->archive,
|
||||
&retdec, dec->source_file,
|
||||
dec->valid_ext, file_decompressed_subdir, &userdata);
|
||||
|
Loading…
x
Reference in New Issue
Block a user