Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bdc3627

Browse files
committed
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.
1 parent 85064ff commit bdc3627

3 files changed

Lines changed: 28 additions & 9 deletions

File tree

Lib/ntpath.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,25 @@ def normpath(path):
440440
"""Normalize path, eliminating double slashes, etc."""
441441
path = path.replace("/", "\\")
442442
prefix, path = splitdrive(path)
443-
while path[:1] == "\\":
444-
prefix = prefix + "\\"
445-
path = path[1:]
443+
# We need to be careful here. If the prefix is empty, and the path starts
444+
# with a backslash, it could either be an absolute path on the current
445+
# drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
446+
# is therefore imperative NOT to collapse multiple backslashes blindly in
447+
# that case.
448+
# The code below preserves multiple backslashes when there is no drive
449+
# letter. This means that the invalid filename \\\a\b is preserved
450+
# unchanged, where a\\\b is normalised to a\b. It's not clear that there
451+
# is any better behaviour for such edge cases.
452+
if prefix == '':
453+
# No drive letter - preserve initial backslashes
454+
while path[:1] == "\\":
455+
prefix = prefix + "\\"
456+
path = path[1:]
457+
else:
458+
# We have a drive letter - collapse initial backslashes
459+
if path.startswith("\\"):
460+
prefix = prefix + "\\"
461+
path = path.lstrip("\\")
446462
comps = path.split("\\")
447463
i = 0
448464
while i < len(comps):

Lib/test/test_ntpath.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,9 @@ def tester(fn, wantResult):
9999
tester("ntpath.normpath('D:A/./B')", r'D:A\B')
100100
tester("ntpath.normpath('e:A/foo/../B')", r'e:A\B')
101101

102-
# Next 3 seem dubious, and especially the 3rd, but normpath is possibly
103-
# trying to leave UNC paths alone without actually knowing anything about
104-
# them.
105-
tester("ntpath.normpath('C:///A//B')", r'C:\\\A\B')
106-
tester("ntpath.normpath('D:///A/./B')", r'D:\\\A\B')
107-
tester("ntpath.normpath('e:///A/foo/../B')", r'e:\\\A\B')
102+
tester("ntpath.normpath('C:///A//B')", r'C:\A\B')
103+
tester("ntpath.normpath('D:///A/./B')", r'D:\A\B')
104+
tester("ntpath.normpath('e:///A/foo/../B')", r'e:\A\B')
108105

109106
tester("ntpath.normpath('..')", r'..')
110107
tester("ntpath.normpath('.')", r'.')
@@ -115,6 +112,8 @@ def tester(fn, wantResult):
115112
tester("ntpath.normpath('c:/../../..')", 'c:\\')
116113
tester("ntpath.normpath('../.././..')", r'..\..\..')
117114
tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
115+
tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
116+
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
118117

119118
# ntpath.abspath() can only be used on a system with the "nt" module
120119
# (reasonably), so we protect this test with "import nt". This allows

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Extension modules
2626
Library
2727
-------
2828

29+
- Bug #980327: ntpath not handles compressing erroneous slashes between the
30+
drive letter and the rest of the path. Also clearly handles UNC addresses now
31+
as well. Thanks Paul Moore.
32+
2933
- bug #679953: zipfile.py should now work for files over 2 GB. The packed data
3034
for file sizes (compressed and uncompressed) was being stored as signed
3135
instead of unsigned.

0 commit comments

Comments
 (0)