diff options
-rw-r--r-- | source/blender/blenlib/intern/path_util.c | 18 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_path_util_test.cc | 25 |
2 files changed, 34 insertions, 9 deletions
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 7c08eeedaa2..3a87b39a446 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -626,10 +626,9 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char bool BLI_path_parent_dir(char *path) { - const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */ - char tmp[FILE_MAX + 4]; + char tmp[FILE_MAX]; - BLI_path_join(tmp, sizeof(tmp), path, parent_dir); + STRNCPY(tmp, path); /* Does all the work of normalizing the path for us. * * NOTE(@campbellbarton): While it's possible strip text after the second last slash, @@ -645,12 +644,19 @@ bool BLI_path_parent_dir(char *path) * which would cause checking for a tailing `/../` fail. * Extracting the span of the final directory avoids both these issues. */ int tail_ofs = 0, tail_len = 0; - if (BLI_path_name_at_index(tmp, -1, &tail_ofs, &tail_len) && (tail_len == 2) && - (memcmp(&tmp[tail_ofs], "..", 2) == 0)) { + if (!BLI_path_name_at_index(tmp, -1, &tail_ofs, &tail_len)) { return false; } + if (tail_len == 1) { + /* Last path is ".", as normalize should remove this, it's safe to assume failure. + * This happens when the input a single period (possibly with slashes before or after). */ + if (tmp[tail_ofs] == '.') { + return false; + } + } - strcpy(path, tmp); /* We assume the parent directory is always shorter. */ + memcpy(path, tmp, tail_ofs); + path[tail_ofs] = '\0'; return true; } diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc index 379ff432988..293d353efcc 100644 --- a/source/blender/blenlib/tests/BLI_path_util_test.cc +++ b/source/blender/blenlib/tests/BLI_path_util_test.cc @@ -102,8 +102,6 @@ TEST(path_util, Clean_Parent) /** \name Tests for: #BLI_path_parent_dir * \{ */ -TEST(path_util, ParentDir) -{ #define PARENT_DIR(input, output) \ { \ char path[FILE_MAX] = input; \ @@ -118,12 +116,25 @@ TEST(path_util, ParentDir) } \ ((void)0) +TEST(path_util, ParentDir_Simple) +{ PARENT_DIR("/a/b/", "/a/"); PARENT_DIR("/a/b", "/a/"); PARENT_DIR("/a", "/"); +} + +TEST(path_util, ParentDir_NOP) +{ PARENT_DIR("/", "/"); PARENT_DIR("", ""); + PARENT_DIR(".", "."); + PARENT_DIR("./", "./"); + PARENT_DIR(".//", ".//"); + PARENT_DIR("./.", "./."); +} +TEST(path_util, ParentDir_TrailingPeriod) +{ /* Ensure trailing dots aren't confused with parent path. */ PARENT_DIR("/.../.../.../", "/.../.../"); PARENT_DIR("/.../.../...", "/.../.../"); @@ -133,10 +144,18 @@ TEST(path_util, ParentDir) PARENT_DIR("/a./b./c./", "/a./b./"); PARENT_DIR("/a./b./c.", "/a./b./"); +} -#undef PARENT_DIR +TEST(path_util, ParentDir_Complex) +{ + PARENT_DIR("./a/", "./"); + PARENT_DIR("./a", "./"); + PARENT_DIR("../a/", "../"); + PARENT_DIR("../a", "../"); } +#undef PARENT_DIR + /** \} */ /* -------------------------------------------------------------------- */ |