Skip to content

Commit

Permalink
pythongh-126780: Fix ntpath.normpath() for drive-relative paths (py…
Browse files Browse the repository at this point in the history
…thonGH-126801)

(cherry picked from commit 60ec854)

Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
  • Loading branch information
nineteendo authored and miss-islington committed Nov 21, 2024
1 parent 6e5e7bc commit f7671da
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
5 changes: 5 additions & 0 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,18 @@ def test_normpath(self):

tester("ntpath.normpath('..')", r'..')
tester("ntpath.normpath('.')", r'.')
tester("ntpath.normpath('c:.')", 'c:')
tester("ntpath.normpath('')", r'.')
tester("ntpath.normpath('/')", '\\')
tester("ntpath.normpath('c:/')", 'c:\\')
tester("ntpath.normpath('/../.././..')", '\\')
tester("ntpath.normpath('c:/../../..')", 'c:\\')
tester("ntpath.normpath('/./a/b')", r'\a\b')
tester("ntpath.normpath('c:/./a/b')", r'c:\a\b')
tester("ntpath.normpath('../.././..')", r'..\..\..')
tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
tester("ntpath.normpath('./a/b')", r'a\b')
tester("ntpath.normpath('c:./a/b')", r'c:a\b')
tester("ntpath.normpath('C:////a/b')", r'C:\a\b')
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')

Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_posixpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ def test_expanduser_pwd2(self):
("/.", "/"),
("/./", "/"),
("/.//.", "/"),
("/./foo/bar", "/foo/bar"),
("/foo", "/foo"),
("/foo/bar", "/foo/bar"),
("//", "//"),
Expand All @@ -388,6 +389,7 @@ def test_expanduser_pwd2(self):
("///..//./foo/.//bar", "/foo/bar"),
(".", "."),
(".//.", "."),
("./foo/bar", "foo/bar"),
("..", ".."),
("../", ".."),
("../foo", "../foo"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix :func:`os.path.normpath` for drive-relative paths on Windows.
51 changes: 26 additions & 25 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2506,37 +2506,38 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
#endif
#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x))

if (p1[0] == L'.' && IS_SEP(&p1[1])) {
// Skip leading '.\'
path = &path[2];
while (IS_SEP(path)) {
path++;
}
p1 = p2 = minP2 = path;
lastC = SEP;
}
else {
Py_ssize_t drvsize, rootsize;
_Py_skiproot(path, size, &drvsize, &rootsize);
if (drvsize || rootsize) {
// Skip past root and update minP2
p1 = &path[drvsize + rootsize];
Py_ssize_t drvsize, rootsize;
_Py_skiproot(path, size, &drvsize, &rootsize);
if (drvsize || rootsize) {
// Skip past root and update minP2
p1 = &path[drvsize + rootsize];
#ifndef ALTSEP
p2 = p1;
p2 = p1;
#else
for (; p2 < p1; ++p2) {
if (*p2 == ALTSEP) {
*p2 = SEP;
}
for (; p2 < p1; ++p2) {
if (*p2 == ALTSEP) {
*p2 = SEP;
}
}
#endif
minP2 = p2 - 1;
lastC = *minP2;
minP2 = p2 - 1;
lastC = *minP2;
#ifdef MS_WINDOWS
if (lastC != SEP) {
minP2++;
}
if (lastC != SEP) {
minP2++;
}
#endif
}
if (p1[0] == L'.' && SEP_OR_END(&p1[1])) {
// Skip leading '.\'
lastC = *++p1;
#ifdef ALTSEP
if (lastC == ALTSEP) {
lastC = SEP;
}
#endif
while (IS_SEP(p1)) {
p1++;
}
}

Expand Down

0 comments on commit f7671da

Please sign in to comment.