diff options
author | Finn Womack <flan313@gmail.com> | 2023-08-15 08:33:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-15 16:33:00 +0100 |
commit | 09322724319d4c23195300b222a1c0ea720af56b (patch) | |
tree | be1ef6bd2798a63e4a9516e5cedeff57f92de670 /Python | |
parent | 607f18c89456cdc9064e27f86a7505e011209757 (diff) | |
download | cpython-09322724319d4c23195300b222a1c0ea720af56b.tar.gz cpython-09322724319d4c23195300b222a1c0ea720af56b.zip |
gh-106242: Fix path truncation in os.path.normpath (GH-106816)
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 19b23f6bd18..0ffd9885fdc 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -2377,12 +2377,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 (!path[0] && size < 0 || size == 0) { + *normsize = 0; return path; } wchar_t *pEnd = size >= 0 ? &path[size] : NULL; @@ -2431,11 +2433,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 @@ -2495,13 +2493,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. |