From 95f02d12f472e994c01fcdfe5085bc0a316e41a6 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Wed, 17 Sep 2014 18:41:23 +0200 Subject: [PATCH 1/3] Basenames should now be correct also when using zipfiles. It is now always only the basename of the file in the zipfile. So if zipname == internalname, its zipname, like requested here: https://github.com/libretro/RetroArch/issues/1030#issuecomment-55810822 --- file_path.c | 16 ++++++++++++++++ retroarch.c | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/file_path.c b/file_path.c index 4ff3f5911a..0c305156fd 100644 --- a/file_path.c +++ b/file_path.c @@ -417,6 +417,22 @@ void fill_pathname_base(char *out, const char *in_path, size_t size) else ptr = in_path; + /* In case of compression, we also have to consider paths like + * /path/to/archive.7z#mygame.img + * and + * /path/to/archive.7z#folder/mygame.img + * basename would be mygame.img in both cases + */ + +#ifdef HAVE_COMPRESSION + const char *ptr_bak = ptr; + ptr = strchr(ptr,'#'); + if (ptr) + ptr++; + else + ptr = ptr_bak; +#endif + rarch_assert(strlcpy(out, ptr, size) < size); } diff --git a/retroarch.c b/retroarch.c index 1cb7268cb7..4b1ba0e323 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1022,7 +1022,7 @@ static void set_basename(const char *path) char *dst = NULL; strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); - strlcpy(g_extern.basename, path, sizeof(g_extern.basename)); + fill_pathname_base(g_extern.basename, path, sizeof(g_extern.basename)); if ((dst = strrchr(g_extern.basename, '.'))) *dst = '\0'; From dd892712ad259024762c64f815e436395b328cf2 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Wed, 17 Sep 2014 18:44:48 +0200 Subject: [PATCH 2/3] if want_miniz is 0, zlib is compiled in regardless. Fixes makefile to allow that. --- Makefile.common | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.common b/Makefile.common index d11d06c4ce..e8567377ab 100644 --- a/Makefile.common +++ b/Makefile.common @@ -557,12 +557,14 @@ ifeq ($(WANT_MINIZ),1) deps/rzlib/ioapi.o \ deps/rzlib/unzip.o else +ifeq ($(HAVE_ZLIB),1) ZLIB_OBJS = deps/rzlib/unzip.o deps/rzlib/ioapi.o OBJ += $(ZLIB_OBJS) RETROLAUNCH_OBJ += $(ZLIB_OBJS) JOYCONFIG_OBJ += $(ZLIB_OBJS) HAVE_ZLIB_DEFLATE = 1 endif +endif ifeq ($(HAVE_ZLIB_DEFLATE),1) DEFINES += -DHAVE_ZLIB_DEFLATE From 757f7d96c2292b9c6e6d6a6511556aae8204e194 Mon Sep 17 00:00:00 2001 From: Timo Strunk Date: Wed, 17 Sep 2014 19:46:59 +0200 Subject: [PATCH 3/3] Now path is also correctly sanitized. g_extern.basename of /path/to/file.zip#game.img is now /path/to/game --- file_path.c | 22 ++++++++++++++++++++-- retroarch.c | 25 ++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/file_path.c b/file_path.c index 0c305156fd..b9f505075b 100644 --- a/file_path.c +++ b/file_path.c @@ -426,7 +426,7 @@ void fill_pathname_base(char *out, const char *in_path, size_t size) #ifdef HAVE_COMPRESSION const char *ptr_bak = ptr; - ptr = strchr(ptr,'#'); + ptr = strchr(ptr_bak,'#'); if (ptr) ptr++; else @@ -466,7 +466,16 @@ void path_basedir(char *path) if (strlen(path) < 2) return; - char *last = find_last_slash(path); + char *last; + +#ifdef HAVE_COMPRESSION + /* We want to find the directory with the zipfile in basedir. */ + last = strchr(path,'#'); + if (last) + *last = '\0'; +#endif + + last = find_last_slash(path); if (last) last[1] = '\0'; @@ -486,6 +495,15 @@ const char *path_basename(const char *path) { const char *last = find_last_slash(path); + /* We cut either at the last hash or the last slash; whichever comes last */ +#ifdef HAVE_COMPRESSION + const char *last_hash = strchr(path,'#'); + if (last_hash > last) + { + return last_hash + 1; + } +#endif + if (last) return last + 1; return path; diff --git a/retroarch.c b/retroarch.c index 4b1ba0e323..5a3ea074ea 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1022,7 +1022,30 @@ static void set_basename(const char *path) char *dst = NULL; strlcpy(g_extern.fullpath, path, sizeof(g_extern.fullpath)); - fill_pathname_base(g_extern.basename, path, sizeof(g_extern.basename)); + strlcpy(g_extern.basename, path, sizeof(g_extern.basename)); + /* Removing extension is a bit tricky for compressed files. + * Basename means: + * /file/to/path/game.extension should be: + * /file/to/path/game + * + * Two things to consider here are: /file/to/path/ is expected + * to be a directory and "game" is a single file. This is used for + * states and srm default paths + * + * For compressed files we have: + * + * /file/to/path/comp.7z#game.extension and + * /file/to/path/comp.7z#folder/game.extension + * + * The choice I take here is: + * /file/to/path/game as basename. We might end up in a writable dir then + * and the name of srm and states are meaningful. + * + */ +#ifdef HAVE_COMPRESSION + path_basedir(g_extern.basename); + fill_pathname_dir(g_extern.basename,path,"",sizeof(g_extern.basename)); +#endif if ((dst = strrchr(g_extern.basename, '.'))) *dst = '\0';