diff options
author | Steve Dower <steve.dower@python.org> | 2023-08-15 17:07:52 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-15 17:07:52 (GMT) |
commit | ccf81e1088c25a9f4464e478dc3b5c03ed7ee63b (patch) | |
tree | e20a6658cef218078316144b6e7644fa4ba2fe18 /Python | |
parent | db4400b5b28dc17c9eac47780402c0b812703358 (diff) | |
download | cpython-ccf81e1088c25a9f4464e478dc3b5c03ed7ee63b.zip cpython-ccf81e1088c25a9f4464e478dc3b5c03ed7ee63b.tar.gz cpython-ccf81e1088c25a9f4464e478dc3b5c03ed7ee63b.tar.bz2 |
[3.11] gh-106242: Fix path truncation in os.path.normpath (GH-106816) (#107982)
Co-authored-by: Finn Womack <flan313@gmail.com>
Diffstat (limited to 'Python')
-rw-r--r-- | Python/fileutils.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/Python/fileutils.c b/Python/fileutils.c index c86ed40..b310a6c 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2179,12 +2179,14 @@ _Py_find_basename(const wchar_t *filename) path, which will be within the original buffer. Guaranteed to not make the path longer, and will not fail. 'size' is the length of the path, if known. If -1, the first null character will be assumed - to be the end of the path. */ + to be the end of the path. 'normsize' will be set to contain the + length of the resulting normalized path. */ wchar_t * -_Py_normpath(wchar_t *path, Py_ssize_t size) +_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) { assert(path != NULL); - if (!path[0] || size == 0) { + if ((size < 0 && !path[0]) || size == 0) { + *normsize = 0; return path; } wchar_t *pEnd = size >= 0 ? &path[size] : NULL; @@ -2233,11 +2235,7 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) *p2++ = lastC = *p1; } } - if (sepCount) { - minP2 = p2; // Invalid path - } else { - minP2 = p2 - 1; // Absolute path has SEP at minP2 - } + minP2 = p2 - 1; } #else // Skip past two leading SEPs @@ -2297,13 +2295,28 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) while (--p2 != minP2 && *p2 == SEP) { *p2 = L'\0'; } + } else { + --p2; } + *normsize = p2 - path + 1; #undef SEP_OR_END #undef IS_SEP #undef IS_END return path; } +/* In-place path normalisation. Returns the start of the normalized + path, which will be within the original buffer. Guaranteed to not + make the path longer, and will not fail. 'size' is the length of + the path, if known. If -1, the first null character will be assumed + to be the end of the path. */ +wchar_t * +_Py_normpath(wchar_t *path, Py_ssize_t size) +{ + Py_ssize_t norm_length; + return _Py_normpath_and_size(path, size, &norm_length); +} + /* Get the current directory. buflen is the buffer size in wide characters including the null character. Decode the path from the locale encoding. |