size_t bufsize);
extern size_t _Py_find_basename(const wchar_t *filename);
PyAPI_FUNC(wchar_t*) _Py_normpath(wchar_t *path, Py_ssize_t size);
+extern wchar_t *_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *length);
// The Windows Games API family does not provide these functions
// so provide our own implementations. Remove them in case they get added
for path in ('', '.', '/', '\\', '///foo/.//bar//'):
self.assertIsInstance(self.pathmodule.normpath(path), str)
+ def test_normpath_issue106242(self):
+ for path in ('\x00', 'foo\x00bar', '\x00\x00', '\x00foo', 'foo\x00'):
+ self.assertEqual(self.pathmodule.normpath(path), path)
+
def test_abspath_issue3426(self):
# Check that abspath returns unicode when the arg is unicode
# with both ASCII and non-ASCII cwds.
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;
*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
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.