mirror of
https://github.com/python/cpython.git
synced 2025-10-15 03:10:29 +00:00
gh-126780: Fix ntpath.normpath()
for drive-relative paths (GH-126801)
This commit is contained in:
parent
0c5556fcb7
commit
60ec854bc2
4 changed files with 34 additions and 25 deletions
|
@ -347,13 +347,18 @@ class TestNtpath(NtpathTestCase):
|
||||||
|
|
||||||
tester("ntpath.normpath('..')", r'..')
|
tester("ntpath.normpath('..')", r'..')
|
||||||
tester("ntpath.normpath('.')", r'.')
|
tester("ntpath.normpath('.')", r'.')
|
||||||
|
tester("ntpath.normpath('c:.')", 'c:')
|
||||||
tester("ntpath.normpath('')", r'.')
|
tester("ntpath.normpath('')", r'.')
|
||||||
tester("ntpath.normpath('/')", '\\')
|
tester("ntpath.normpath('/')", '\\')
|
||||||
tester("ntpath.normpath('c:/')", 'c:\\')
|
tester("ntpath.normpath('c:/')", 'c:\\')
|
||||||
tester("ntpath.normpath('/../.././..')", '\\')
|
tester("ntpath.normpath('/../.././..')", '\\')
|
||||||
tester("ntpath.normpath('c:/../../..')", 'c:\\')
|
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('../.././..')", r'..\..\..')
|
||||||
tester("ntpath.normpath('K:../.././..')", r'K:..\..\..')
|
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('C:////a/b')", r'C:\a\b')
|
||||||
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
|
tester("ntpath.normpath('//machine/share//a/b')", r'\\machine\share\a\b')
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,7 @@ class PosixPathTest(unittest.TestCase):
|
||||||
("/.", "/"),
|
("/.", "/"),
|
||||||
("/./", "/"),
|
("/./", "/"),
|
||||||
("/.//.", "/"),
|
("/.//.", "/"),
|
||||||
|
("/./foo/bar", "/foo/bar"),
|
||||||
("/foo", "/foo"),
|
("/foo", "/foo"),
|
||||||
("/foo/bar", "/foo/bar"),
|
("/foo/bar", "/foo/bar"),
|
||||||
("//", "//"),
|
("//", "//"),
|
||||||
|
@ -388,6 +389,7 @@ class PosixPathTest(unittest.TestCase):
|
||||||
("///..//./foo/.//bar", "/foo/bar"),
|
("///..//./foo/.//bar", "/foo/bar"),
|
||||||
(".", "."),
|
(".", "."),
|
||||||
(".//.", "."),
|
(".//.", "."),
|
||||||
|
("./foo/bar", "foo/bar"),
|
||||||
("..", ".."),
|
("..", ".."),
|
||||||
("../", ".."),
|
("../", ".."),
|
||||||
("../foo", "../foo"),
|
("../foo", "../foo"),
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix :func:`os.path.normpath` for drive-relative paths on Windows.
|
|
@ -2506,37 +2506,38 @@ _Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize)
|
||||||
#endif
|
#endif
|
||||||
#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x))
|
#define SEP_OR_END(x) (IS_SEP(x) || IS_END(x))
|
||||||
|
|
||||||
if (p1[0] == L'.' && IS_SEP(&p1[1])) {
|
Py_ssize_t drvsize, rootsize;
|
||||||
// Skip leading '.\'
|
_Py_skiproot(path, size, &drvsize, &rootsize);
|
||||||
path = &path[2];
|
if (drvsize || rootsize) {
|
||||||
while (IS_SEP(path)) {
|
// Skip past root and update minP2
|
||||||
path++;
|
p1 = &path[drvsize + rootsize];
|
||||||
}
|
|
||||||
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];
|
|
||||||
#ifndef ALTSEP
|
#ifndef ALTSEP
|
||||||
p2 = p1;
|
p2 = p1;
|
||||||
#else
|
#else
|
||||||
for (; p2 < p1; ++p2) {
|
for (; p2 < p1; ++p2) {
|
||||||
if (*p2 == ALTSEP) {
|
if (*p2 == ALTSEP) {
|
||||||
*p2 = SEP;
|
*p2 = SEP;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
minP2 = p2 - 1;
|
minP2 = p2 - 1;
|
||||||
lastC = *minP2;
|
lastC = *minP2;
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (lastC != SEP) {
|
if (lastC != SEP) {
|
||||||
minP2++;
|
minP2++;
|
||||||
}
|
}
|
||||||
#endif
|
#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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue