From cc7541338c766cf7bacba721d977ca93444d1ebb Mon Sep 17 00:00:00 2001 From: krzys-h Date: Mon, 14 Jan 2019 20:42:06 +0100 Subject: [PATCH] Fix parent of root directory turning into ./ on Windows (#7803) --- libretro-common/file/file_path.c | 15 +++++++++++++++ libretro-common/include/file/file_path.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 6db4f005e8..c2d9459908 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -693,6 +693,7 @@ bool fill_pathname_parent_dir_name(char *out_dir, * * Copies parent directory of @in_dir into @out_dir. * Assumes @in_dir is a directory. Keeps trailing '/'. + * If the path was already at the root directory, @out_dir will be an empty string. **/ void fill_pathname_parent_dir(char *out_dir, const char *in_dir, size_t size) @@ -779,12 +780,26 @@ void path_basedir(char *path) * * Extracts parent directory by mutating path. * Assumes that path is a directory. Keeps trailing '/'. + * If the path was already at the root directory, returns empty string **/ void path_parent_dir(char *path) { + bool path_was_absolute = path_is_absolute(path); size_t len = strlen(path); if (len && path_char_is_slash(path[len - 1])) + { path[len - 1] = '\0'; + if (path_was_absolute && find_last_slash(path) == NULL) + { + /* We removed the only slash from what used to be an absolute path. + * On Linux, this goes from "/" to an empty string and everything works fine, + * but on Windows, we went from C:\ to C:, which is not a valid path and that later + * gets errornously treated as a relative one by path_basedir and returns "./". + * What we really wanted is an empty string. */ + path[0] = '\0'; + return; + } + } path_basedir(path); } diff --git a/libretro-common/include/file/file_path.h b/libretro-common/include/file/file_path.h index 51adab9f1f..c6896e05ab 100644 --- a/libretro-common/include/file/file_path.h +++ b/libretro-common/include/file/file_path.h @@ -136,6 +136,7 @@ void path_basedir(char *path); * * Extracts parent directory by mutating path. * Assumes that path is a directory. Keeps trailing '/'. + * If the path was already at the root directory, returns empty string **/ void path_parent_dir(char *path); @@ -314,6 +315,7 @@ bool fill_pathname_parent_dir_name(char *out_dir, * * Copies parent directory of @in_dir into @out_dir. * Assumes @in_dir is a directory. Keeps trailing '/'. + * If the path was already at the root directory, @out_dir will be an empty string. **/ void fill_pathname_parent_dir(char *out_dir, const char *in_dir, size_t size);