]> granicus.if.org Git - python/commitdiff
SF bug #456621: normpath on Win32 not collapsing c:\\..
authorTim Peters <tim.peters@gmail.com>
Thu, 30 Aug 2001 22:05:26 +0000 (22:05 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 30 Aug 2001 22:05:26 +0000 (22:05 +0000)
I actually rewrote normpath quite a bit:  it had no test cases, and as
soon as I starting writing some I found several cases that didn't make
sense.

Lib/ntpath.py
Lib/test/test_ntpath.py

index 1be2961a4f871573b4e54c852d15fcb4cedf4d19..d55cc7c44f3ec693cce49046d66bc596888ce262 100644 (file)
@@ -407,7 +407,7 @@ def expandvars(path):
     return res
 
 
-# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B.
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
 # Previously, this function also truncated pathnames to 8+3 format,
 # but as this module is called "ntpath", that's obviously wrong!
 
@@ -421,15 +421,18 @@ def normpath(path):
     comps = path.split("\\")
     i = 0
     while i < len(comps):
-        if comps[i] == '.':
-            del comps[i]
-        elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'):
-            del comps[i-1:i+1]
-            i = i - 1
-        elif comps[i] == '' and i > 0 and comps[i-1] != '':
+        if comps[i] in ('.', ''):
             del comps[i]
+        elif comps[i] == '..':
+            if i > 0 and comps[i-1] != '..':
+                del comps[i-1:i+1]
+                i -= 1
+            elif i == 0 and prefix.endswith("\\"):
+                del comps[i]
+            else:
+                i += 1
         else:
-            i = i + 1
+            i += 1
     # If the path is now empty, substitute '.'
     if not prefix and not comps:
         comps.append('.')
index fe997b31284825d65cb6d54382e3350b8e34d689..049bbc1c26284a904afe45d06928d2865f529f66 100644 (file)
@@ -74,6 +74,30 @@ tester("ntpath.join('c:', 'd:/')", 'd:/')
 tester("ntpath.join('c:/', 'd:/')", 'd:/')
 tester("ntpath.join('c:/', 'd:/a/b')", 'd:/a/b')
 
+tester("ntpath.normpath('A//////././//.//B')", r'A\B')
+tester("ntpath.normpath('A/./B')", r'A\B')
+tester("ntpath.normpath('A/foo/../B')", r'A\B')
+tester("ntpath.normpath('C:A//B')", r'C:A\B')
+tester("ntpath.normpath('D:A/./B')", r'D:A\B')
+tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B')
+
+# Next 3 seem dubious, and especially the 3rd, but normpath is possibly
+# trying to leave UNC paths alone without actually knowing anything about
+# them.
+tester("ntpath.normpath('C:///A//B')", r'C:\\\A\B')
+tester("ntpath.normpath('D:///A/./B')", r'D:\\\A\B')
+tester("ntpath.normpath('e:///A/foo/../B')", r'e:\\\A\B')
+
+tester("ntpath.normpath('..')", r'..')
+tester("ntpath.normpath('.')", r'.')
+tester("ntpath.normpath('')", r'.')
+tester("ntpath.normpath('/')", '\\')
+tester("ntpath.normpath('c:/')", 'c:\\')
+tester("ntpath.normpath('/../.././..')", '\\')
+tester("ntpath.normpath('c:/../../..')", 'c:\\')
+tester("ntpath.normpath('../.././..')", r'..\..\..')
+tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
+
 if errors:
     raise TestFailed(str(errors) + " errors.")
 elif verbose: