[Bf-blender-cvs] [cc6f41f8a53] master: Fix BLI_path_parent_dir failing on paths ending with ".."

Campbell Barton noreply at git.blender.org
Tue Nov 1 21:22:59 CET 2022


Commit: cc6f41f8a53f7f0392afa59e6da8ebc3849fc03c
Author: Campbell Barton
Date:   Tue Nov 1 22:02:08 2022 +1100
Branches: master
https://developer.blender.org/rBcc6f41f8a53f7f0392afa59e6da8ebc3849fc03c

Fix BLI_path_parent_dir failing on paths ending with ".."

The check for BLI_path_normalize having succeeded only checked for a
trailing "../" which isn't correct. This caused going up a directory
in the file selector to do nothing on directories ending with "..".

This also caused an empty path to expand into "../" because
BLI_path_extension_check didn't account for this case.

Resolve using BLI_path_name_at_index which extracts the last component
of the path without having to match the the surrounding slashes.

===================================================================

M	source/blender/blenlib/BLI_path_util.h
M	source/blender/blenlib/intern/path_util.c
M	source/blender/blenlib/tests/BLI_path_util_test.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 6d411b51f85..1b723ab038d 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -364,6 +364,8 @@ bool BLI_path_make_safe(char *path) ATTR_NONNULL(1);
  *
  * Replaces path with the path of its parent directory, returning true if
  * it was able to find a parent directory within the path.
+ *
+ * On success, the resulting path will always have a trailing slash.
  */
 bool BLI_path_parent_dir(char *path) ATTR_NONNULL();
 /**
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index df18689c74c..f46c2e65395 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -630,14 +630,28 @@ bool BLI_path_parent_dir(char *path)
   char tmp[FILE_MAX + 4];
 
   BLI_path_join(tmp, sizeof(tmp), path, parent_dir);
-  BLI_path_normalize(NULL, tmp); /* does all the work of normalizing the path for us */
-
-  if (!BLI_path_extension_check(tmp, parent_dir)) {
-    strcpy(path, tmp); /* We assume the parent directory is always shorter. */
-    return true;
+  /* Does all the work of normalizing the path for us.
+   *
+   * NOTE(@campbellbarton): While it's possible strip text after the second last slash,
+   * this would have to be clever and skip cases like "/./" & multiple slashes.
+   * Since this ends up solving some of the same problems as #BLI_path_normalize,
+   * call this function instead of attempting to handle them separately. */
+  BLI_path_normalize(NULL, tmp);
+
+  /* Use #BLI_path_name_at_index instead of checking if the strings ends with `parent_dir`
+   * to ensure the logic isn't confused by:
+   * - Directory names that happen to end with `..`.
+   * - When `path` is empty, the contents will be `../`
+   *   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)) {
+    return false;
   }
 
-  return false;
+  strcpy(path, tmp); /* We assume the parent directory is always shorter. */
+  return true;
 }
 
 bool BLI_path_parent_dir_until_exists(char *dir)
diff --git a/source/blender/blenlib/tests/BLI_path_util_test.cc b/source/blender/blenlib/tests/BLI_path_util_test.cc
index 51db376e03f..93922b41b23 100644
--- a/source/blender/blenlib/tests/BLI_path_util_test.cc
+++ b/source/blender/blenlib/tests/BLI_path_util_test.cc
@@ -75,6 +75,17 @@ TEST(path_util, ParentDir)
   PARENT_DIR("/a/b", "/a/");
   PARENT_DIR("/a", "/");
   PARENT_DIR("/", "/");
+  PARENT_DIR("", "");
+
+  /* Ensure trailing dots aren't confused with parent path. */
+  PARENT_DIR("/.../.../.../", "/.../.../");
+  PARENT_DIR("/.../.../...", "/.../.../");
+
+  PARENT_DIR("/a../b../c../", "/a../b../");
+  PARENT_DIR("/a../b../c..", "/a../b../");
+
+  PARENT_DIR("/a./b./c./", "/a./b./");
+  PARENT_DIR("/a./b./c.", "/a./b./");
 
 #  undef PARENT_DIR
 }



More information about the Bf-blender-cvs mailing list