Make ntpath compress multiple slashes between drive letter and the rest of the

path.  Also clarifies UNC handling and adds appropriate tests.

Applies patch #988607 to fix bug #980327.  Thanks Paul Moore.
This commit is contained in:
Brett Cannon 2004-07-10 20:42:22 +00:00
parent 85064ffd76
commit bdc36273a2
3 changed files with 28 additions and 9 deletions

View File

@ -440,9 +440,25 @@ def normpath(path):
"""Normalize path, eliminating double slashes, etc.""" """Normalize path, eliminating double slashes, etc."""
path = path.replace("/", "\\") path = path.replace("/", "\\")
prefix, path = splitdrive(path) prefix, path = splitdrive(path)
# 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] == "\\": while path[:1] == "\\":
prefix = prefix + "\\" prefix = prefix + "\\"
path = path[1:] path = path[1:]
else:
# We have a drive letter - collapse initial backslashes
if path.startswith("\\"):
prefix = prefix + "\\"
path = path.lstrip("\\")
comps = path.split("\\") comps = path.split("\\")
i = 0 i = 0
while i < len(comps): while i < len(comps):

View File

@ -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('D:A/./B')", r'D:A\B')
tester("ntpath.normpath('e:A/foo/../B')", r'e: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 tester("ntpath.normpath('C:///A//B')", r'C:\A\B')
# trying to leave UNC paths alone without actually knowing anything about tester("ntpath.normpath('D:///A/./B')", r'D:\A\B')
# them. 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'..')
tester("ntpath.normpath('.')", r'.') tester("ntpath.normpath('.')", r'.')
@ -115,6 +112,8 @@ tester("ntpath.normpath('/../.././..')", '\\')
tester("ntpath.normpath('c:/../../..')", 'c:\\') tester("ntpath.normpath('c:/../../..')", 'c:\\')
tester("ntpath.normpath('../.././..')", r'..\..\..') tester("ntpath.normpath('../.././..')", r'..\..\..')
tester("ntpath.normpath('K:../.././..')", r'K:..\..\..') 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 # ntpath.abspath() can only be used on a system with the "nt" module
# (reasonably), so we protect this test with "import nt". This allows # (reasonably), so we protect this test with "import nt". This allows

View File

@ -26,6 +26,10 @@ Extension modules
Library Library
------- -------
- Bug #980327: ntpath not handles compressing erroneous slashes between the
drive letter and the rest of the path. Also clearly handles UNC addresses now
as well. Thanks Paul Moore.
- bug #679953: zipfile.py should now work for files over 2 GB. The packed data - bug #679953: zipfile.py should now work for files over 2 GB. The packed data
for file sizes (compressed and uncompressed) was being stored as signed for file sizes (compressed and uncompressed) was being stored as signed
instead of unsigned. instead of unsigned.