From: Brett Cannon Date: Sat, 10 Jul 2004 20:47:29 +0000 (+0000) Subject: ntpath now compresses erroneous slashes between the drive letter and rest of X-Git-Tag: v2.3.5c1~186 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b161cb7edd5a18f7a34f44a652c53b60bb043241;p=thirdparty%2FPython%2Fcpython.git ntpath now compresses erroneous slashes between the drive letter and rest of the path. Also clarifies handling of UNC paths. Appropriate test were added. Fixes bug #980327 with patch #988607. Thanks Paul Moore. --- diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 687d88513e20..65ef6844267b 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -439,9 +439,25 @@ def normpath(path): """Normalize path, eliminating double slashes, etc.""" path = path.replace("/", "\\") prefix, path = splitdrive(path) - while path[:1] == "\\": - prefix = prefix + "\\" - path = path[1:] + # We need to be careful here. If the prefix is empty, and the path starts + # with a backslash, it could either be an absolute path on the current + # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It + # is therefore imperative NOT to collapse multiple backslashes blindly in + # that case. + # The code below preserves multiple backslashes when there is no drive + # letter. This means that the invalid filename \\\a\b is preserved + # unchanged, where a\\\b is normalised to a\b. It's not clear that there + # is any better behaviour for such edge cases. + if prefix == '': + # No drive letter - preserve initial backslashes + while path[:1] == "\\": + prefix = prefix + "\\" + path = path[1:] + else: + # We have a drive letter - collapse initial backslashes + if path.startswith("\\"): + prefix = prefix + "\\" + path = path.lstrip("\\") comps = path.split("\\") i = 0 while i < len(comps): diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index fdb431aa6413..139aa1f28e06 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -99,12 +99,9 @@ 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('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'.') @@ -115,6 +112,8 @@ tester("ntpath.normpath('/../.././..')", '\\') tester("ntpath.normpath('c:/../../..')", 'c:\\') tester("ntpath.normpath('../.././..')", r'..\..\..') tester("ntpath.normpath('K:../.././..')", r'K:..\..\..') +tester("ntpath.normpath('C:////a/b')", r'C:\a\b') +tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b') # ntpath.abspath() can only be used on a system with the "nt" module # (reasonably), so we protect this test with "import nt". This allows diff --git a/Misc/NEWS b/Misc/NEWS index 5d736ee95947..46050d7cb800 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -40,6 +40,10 @@ Extension modules Library ------- +- Bug #980327/Patch #988607: ntpath now compresses extra slashes between the + drive letter and the rest of the path properly. Also removed ambiguity from + UNC paths. Thanks Paul Moore. + - Bug #679953: zipfile can now handle file sizes over 2 GB. Previously the compressed and uncompressed file sizes were being stored as signed longs instead of unsigned as the ZIP spec specifies.