diff options
author | Nice Zombies <nineteendo19d0@gmail.com> | 2024-11-21 14:43:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-21 14:43:36 (GMT) |
commit | 60ec854bc297e04718fe13db3605d0465bf8badb (patch) | |
tree | 98e06da03433b3e10b0ad9ac181bded4cbd6ba48 | |
parent | 0c5556fcb7315f26aa4b192e341cb2a72bb78f41 (diff) | |
download | cpython-60ec854bc297e04718fe13db3605d0465bf8badb.zip cpython-60ec854bc297e04718fe13db3605d0465bf8badb.tar.gz cpython-60ec854bc297e04718fe13db3605d0465bf8badb.tar.bz2 |
gh-126780: Fix `ntpath.normpath()` for drive-relative paths (GH-126801)
-rw-r--r-- | Lib/test/test_ntpath.py | 5 | ||||
-rw-r--r-- | Lib/test/test_posixpath.py | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst | 1 | ||||
-rw-r--r-- | Python/fileutils.c | 51 |
4 files changed, 34 insertions, 25 deletions
diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index 4f59184..6715071 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -347,13 +347,18 @@ class TestNtpath(NtpathTestCase): 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') diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index b39255eb..43e4fbc 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -379,6 +379,7 @@ class PosixPathTest(unittest.TestCase): ("/.", "/"), ("/./", "/"), ("/.//.", "/"), + ("/./foo/bar", "/foo/bar"), ("/foo", "/foo"), ("/foo/bar", "/foo/bar"), ("//", "//"), @@ -388,6 +389,7 @@ class PosixPathTest(unittest.TestCase): ("///..//./foo/.//bar", "/foo/bar"), (".", "."), (".//.", "."), + ("./foo/bar", "foo/bar"), ("..", ".."), ("../", ".."), ("../foo", "../foo"), diff --git a/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst b/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst new file mode 100644 index 0000000..93d45ca --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-11-13-19-15-18.gh-issue-126780.ZZqJvI.rst @@ -0,0 +1 @@ +Fix :func:`os.path.normpath` for drive-relative paths on Windows. diff --git a/Python/fileutils.c b/Python/fileutils.c index c9ae1b3..9529b14 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -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++; } } |