fix more memory corruption

This commit is contained in:
Brad Parker 2016-09-18 15:20:27 -04:00
parent dc4760f5a6
commit a7ffead8f6
6 changed files with 98 additions and 102 deletions

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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))

View File

@ -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);