mirror of
https://github.com/libretro/RetroArch
synced 2025-04-25 09:02:44 +00:00
correctly handle content paths containing a hash (#), fixes issue #3273
This commit is contained in:
parent
db36b40b20
commit
5275c0a45d
@ -37,6 +37,7 @@
|
|||||||
#include <retro_assert.h>
|
#include <retro_assert.h>
|
||||||
#include <retro_stat.h>
|
#include <retro_stat.h>
|
||||||
#include <retro_miscellaneous.h>
|
#include <retro_miscellaneous.h>
|
||||||
|
#include <string/stdstring.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* path_mkdir:
|
* path_mkdir:
|
||||||
@ -137,7 +138,23 @@ char *path_remove_extension(char *path)
|
|||||||
**/
|
**/
|
||||||
bool path_contains_compressed_file(const char *path)
|
bool path_contains_compressed_file(const char *path)
|
||||||
{
|
{
|
||||||
return (strchr(path, '#') != NULL);
|
bool compressed = false;
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPRESSION
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
|
if (strcasestr(path, ".zip#"))
|
||||||
|
compressed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_7ZIP
|
||||||
|
if (strcasestr(path, ".7z#"))
|
||||||
|
compressed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return compressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,12 +171,12 @@ bool path_is_compressed_file(const char* path)
|
|||||||
const char* file_ext = path_get_extension(path);
|
const char* file_ext = path_get_extension(path);
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
if (!strcmp(file_ext, "zip"))
|
if (string_is_equal_noncase(file_ext, "zip"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_7ZIP
|
#ifdef HAVE_7ZIP
|
||||||
if (!strcmp(file_ext, "7z"))
|
if (string_is_equal_noncase(file_ext, "7z"))
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -504,11 +521,20 @@ const char *path_basename(const char *path)
|
|||||||
#ifdef HAVE_COMPRESSION
|
#ifdef HAVE_COMPRESSION
|
||||||
const char *last_hash = NULL;
|
const char *last_hash = NULL;
|
||||||
|
|
||||||
/* We cut either at the last hash or the last slash; whichever comes last */
|
/* We cut either at the first compression-related hash or the last slash; whichever comes last */
|
||||||
last_hash = strchr(path,'#');
|
#ifdef HAVE_ZLIB
|
||||||
|
last_hash = strcasestr(path, ".zip#");
|
||||||
|
|
||||||
if (last_hash > last)
|
if (last_hash > last)
|
||||||
return last_hash + 1;
|
return last_hash + 5;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_7ZIP
|
||||||
|
last_hash = strcasestr(path, ".7z#");
|
||||||
|
|
||||||
|
if (last_hash > last)
|
||||||
|
return last_hash + 4;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (last)
|
if (last)
|
||||||
|
@ -312,6 +312,98 @@ static int content_7zip_file_read(
|
|||||||
return outsize;
|
return outsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int try_insert_compressed_file_to_list(const char *path, const char *ext, unsigned ext_len, char *tmp, struct string_list *list, unsigned index, unsigned *first) {
|
||||||
|
char *ext_with_hash = NULL;
|
||||||
|
|
||||||
|
if(index - (*first) >= ext_len)
|
||||||
|
{
|
||||||
|
ext_with_hash = (char*)malloc(ext_len + 2);
|
||||||
|
memcpy(ext_with_hash, ext, ext_len);
|
||||||
|
ext_with_hash[ext_len] = '#';
|
||||||
|
|
||||||
|
if(strncasecmp(path + (index - ext_len), ext_with_hash, ext_len + 1) == 0)
|
||||||
|
{
|
||||||
|
(*first) = index + 1;
|
||||||
|
strncpy(tmp, path, index);
|
||||||
|
|
||||||
|
union string_list_elem_attr attr;
|
||||||
|
memset(&attr, 0, sizeof(attr));
|
||||||
|
|
||||||
|
if (!string_list_append(list, tmp, attr))
|
||||||
|
{
|
||||||
|
free(ext_with_hash);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(tmp, 0, PATH_MAX_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ext_with_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* filename_split:
|
||||||
|
* @str : filename to turn into a string list
|
||||||
|
* @delim : delimiter character to use for splitting the string.
|
||||||
|
*
|
||||||
|
* Creates a new string list based on filename @path, delimited by @delim.
|
||||||
|
*
|
||||||
|
* Returns: new string list if successful, otherwise NULL.
|
||||||
|
*/
|
||||||
|
struct string_list *filename_split(const char *path, const char *delim)
|
||||||
|
{
|
||||||
|
struct string_list *list = string_list_new();
|
||||||
|
unsigned len = strlen(path);
|
||||||
|
unsigned index = 0;
|
||||||
|
unsigned first = 0;
|
||||||
|
char tmp[PATH_MAX_LENGTH] = {0};
|
||||||
|
|
||||||
|
if (!list)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
#ifdef HAVE_COMPRESSION
|
||||||
|
while(path[index] != 0) {
|
||||||
|
if (path[index] != '#')
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ZLIB
|
||||||
|
if (!try_insert_compressed_file_to_list(path, ".zip", 4, tmp, list, index, &first))
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_7ZIP
|
||||||
|
if (!try_insert_compressed_file_to_list(path, ".7z", 3, tmp, list, index, &first))
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (path + first)
|
||||||
|
{
|
||||||
|
strncpy(tmp, path + first, MIN(len - first, PATH_MAX_LENGTH - 1));
|
||||||
|
|
||||||
|
union string_list_elem_attr attr;
|
||||||
|
memset(&attr, 0, sizeof(attr));
|
||||||
|
|
||||||
|
if (!string_list_append(list, tmp, attr))
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
string_list_free(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct string_list *compressed_7zip_file_list_new(
|
static struct string_list *compressed_7zip_file_list_new(
|
||||||
const char *path, const char* ext)
|
const char *path, const char* ext)
|
||||||
{
|
{
|
||||||
@ -621,7 +713,7 @@ static int content_file_compressed_read(
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
const char* file_ext = NULL;
|
const char* file_ext = NULL;
|
||||||
struct string_list *str_list = string_split(path, "#");
|
struct string_list *str_list = filename_split(path, "#");
|
||||||
|
|
||||||
/* Safety check.
|
/* Safety check.
|
||||||
* If optional_filename and optional_filename
|
* If optional_filename and optional_filename
|
||||||
|
Loading…
x
Reference in New Issue
Block a user