summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2020-02-23 22:22:46 +0300
committerGitHub <noreply@github.com>2020-02-23 20:22:46 +0100
commit3dad130034e3212159dda5d61988ca2b18959b24 (patch)
tree61b51d8a2305a18ca0e0551fdb30b07e670fc5ee
parent13d292786e5a43b23f9a48643744c121c244b6ed (diff)
downloadNim-3dad130034e3212159dda5d61988ca2b18959b24.tar.gz
fix 3 minor bugs in joinPath (see #13455) (#13462) [backport]
-rw-r--r--changelog.md2
-rw-r--r--lib/pure/os.nim3
-rw-r--r--lib/pure/pathnorm.nim3
-rw-r--r--tests/stdlib/tos.nim4
4 files changed, 10 insertions, 2 deletions
diff --git a/changelog.md b/changelog.md
index d929ea0d9..5041f4d7e 100644
--- a/changelog.md
+++ b/changelog.md
@@ -129,3 +129,5 @@
 
 - The `FD` variant of `selector.unregister` for `ioselector_epoll` and
   `ioselector_select` now properly handle the `Event.User` select event type.
+- `joinPath` path normalization when `/` is the first argument works correctly:
+  `assert "/" / "/a" == "/a"`. Fixed the edgecase: `assert "" / "" == ""`.
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index aff91fccb..5bdc5e11d 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -141,6 +141,7 @@ proc joinPath*(head, tail: string): string {.
     when defined(posix):
       assert joinPath("usr", "lib") == "usr/lib"
       assert joinPath("usr", "") == "usr/"
+      assert joinPath("", "") == ""
       assert joinPath("", "lib") == "lib"
       assert joinPath("", "/lib") == "/lib"
       assert joinPath("usr/", "/lib") == "usr/lib"
@@ -149,7 +150,7 @@ proc joinPath*(head, tail: string): string {.
   result = newStringOfCap(head.len + tail.len)
   var state = 0
   addNormalizePath(head, result, state, DirSep)
-  if tail.len == 0:
+  if result.len != 0 and result[^1] notin {DirSep, AltSep} and tail.len == 0:
     result.add DirSep
   else:
     addNormalizePath(tail, result, state, DirSep)
diff --git a/lib/pure/pathnorm.nim b/lib/pure/pathnorm.nim
index 407ec156c..3659e85e6 100644
--- a/lib/pure/pathnorm.nim
+++ b/lib/pure/pathnorm.nim
@@ -69,7 +69,8 @@ proc addNormalizePath*(x: string; result: var string; state: var int;
   while hasNext(it, x):
     let b = next(it, x)
     if (state shr 1 == 0) and isSlash(x, b):
-      result.add dirSep
+      if result.len == 0 or result[^1] notin {DirSep, AltSep}:
+        result.add dirSep
       state = state or 1
     elif isDotDot(x, b):
       if (state shr 1) >= 1:
diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim
index 02a449b8c..15b82fadf 100644
--- a/tests/stdlib/tos.nim
+++ b/tests/stdlib/tos.nim
@@ -361,6 +361,10 @@ block ospaths:
   doAssert joinPath("", "lib") == "lib"
   doAssert joinPath("", "/lib") == unixToNativePath"/lib"
   doAssert joinPath("usr/", "/lib") == unixToNativePath"usr/lib"
+  doAssert joinPath("", "") == unixToNativePath""
+  doAssert joinPath("/" / "") == unixToNativePath"/"
+  doAssert joinPath("/", "/a/b/c") == unixToNativePath"/a/b/c"
+  doAssert joinPath("foo/","") == unixToNativePath"foo/"
 
 block getTempDir:
   block TMPDIR: