Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions Include/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,25 @@ PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
PyAPI_FUNC(int) _Py_wreadlink(
const wchar_t *path,
wchar_t *buf,
size_t bufsiz);
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);
#endif

#ifdef HAVE_REALPATH
PyAPI_FUNC(wchar_t*) _Py_wrealpath(
const wchar_t *path,
wchar_t *resolved_path,
size_t resolved_path_size);
/* Number of characters of 'resolved_path' buffer
including the trailing NUL character */
size_t resolved_path_len);
#endif

PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
wchar_t *buf,
size_t size);
/* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);

PyAPI_FUNC(int) _Py_get_inheritable(int fd);

Expand Down
35 changes: 21 additions & 14 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1629,10 +1629,12 @@ _Py_write_noraise(int fd, const void *buf, size_t count)
#ifdef HAVE_READLINK

/* Read value of symbolic link. Encode the path to the locale encoding, decode
the result from the locale encoding. Return -1 on error. */
the result from the locale encoding.

Return -1 on encoding error, on readlink() error, if the internal buffer is
too short, on decoding error, or if 'buf' is too short. */
int
_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t buflen)
{
char *cpath;
char cbuf[MAXPATHLEN];
Expand All @@ -1659,12 +1661,13 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
errno = EINVAL;
return -1;
}
if (bufsiz <= r1) {
/* wbuf must have space to store the trailing NUL character */
if (buflen <= r1) {
PyMem_RawFree(wbuf);
errno = EINVAL;
return -1;
}
wcsncpy(buf, wbuf, bufsiz);
wcsncpy(buf, wbuf, buflen);
PyMem_RawFree(wbuf);
return (int)r1;
}
Expand All @@ -1674,11 +1677,12 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)

/* Return the canonicalized absolute pathname. Encode path to the locale
encoding, decode the result from the locale encoding.
Return NULL on error. */

Return NULL on encoding error, realpath() error, decoding error
or if 'resolved_path' is too short. */
wchar_t*
_Py_wrealpath(const wchar_t *path,
wchar_t *resolved_path, size_t resolved_path_size)
wchar_t *resolved_path, size_t resolved_path_len)
{
char *cpath;
char cresolved_path[MAXPATHLEN];
Expand All @@ -1700,27 +1704,29 @@ _Py_wrealpath(const wchar_t *path,
errno = EINVAL;
return NULL;
}
if (resolved_path_size <= r) {
/* wresolved_path must have space to store the trailing NUL character */
if (resolved_path_len <= r) {
PyMem_RawFree(wresolved_path);
errno = EINVAL;
return NULL;
}
wcsncpy(resolved_path, wresolved_path, resolved_path_size);
wcsncpy(resolved_path, wresolved_path, resolved_path_len);
PyMem_RawFree(wresolved_path);
return resolved_path;
}
#endif

/* Get the current directory. size is the buffer size in wide characters
including the null character. Decode the path from the locale encoding.
Return NULL on error. */

Return NULL on getcwd() error, on decoding error, or if 'buf' is
too short. */
wchar_t*
_Py_wgetcwd(wchar_t *buf, size_t size)
_Py_wgetcwd(wchar_t *buf, size_t buflen)
{
#ifdef MS_WINDOWS
int isize = (int)Py_MIN(size, INT_MAX);
return _wgetcwd(buf, isize);
int ibuflen = (int)Py_MIN(buflen, INT_MAX);
return _wgetcwd(buf, ibuflen);
#else
char fname[MAXPATHLEN];
wchar_t *wname;
Expand All @@ -1731,11 +1737,12 @@ _Py_wgetcwd(wchar_t *buf, size_t size)
wname = Py_DecodeLocale(fname, &len);
if (wname == NULL)
return NULL;
if (size <= len) {
/* wname must have space to store the trailing NUL character */
if (buflen <= len) {
PyMem_RawFree(wname);
return NULL;
}
wcsncpy(buf, wname, size);
wcsncpy(buf, wname, buflen);
PyMem_RawFree(wname);
return buf;
#endif
Expand Down