summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2023-08-15 17:07:52 (GMT)
committerGitHub <noreply@github.com>2023-08-15 17:07:52 (GMT)
commitccf81e1088c25a9f4464e478dc3b5c03ed7ee63b (patch)
treee20a6658cef218078316144b6e7644fa4ba2fe18 /Python
parentdb4400b5b28dc17c9eac47780402c0b812703358 (diff)
downloadcpython-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.c29
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.