diff options
author | Steve Dower <steve.dower@python.org> | 2023-08-16 23:19:48 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-16 23:19:48 (GMT) |
commit | ede98958810b76694cf756d305b564cd6adc1a48 (patch) | |
tree | 89b00419836960b648ab4104277db32c45e9ad14 /Python/fileutils.c | |
parent | 2a00cf2db8a19533dc7d71276ce6a77f6a103c65 (diff) | |
download | cpython-ede98958810b76694cf756d305b564cd6adc1a48.zip cpython-ede98958810b76694cf756d305b564cd6adc1a48.tar.gz cpython-ede98958810b76694cf756d305b564cd6adc1a48.tar.bz2 |
[3.12] gh-106242: Fix path truncation in os.path.normpath (GH-106816) (#107981)
* gh-106242: Fix path truncation in os.path.normpath (GH-106816)
* gh-106242: Minor fixup to avoid compiler warnings
---------
Co-authored-by: Finn Womack <flan313@gmail.com>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Python/fileutils.c')
-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 f137ee9..268ffa3 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 ((size < 0 && !path[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. |