bpo-36352: Clarify fileutils.h documentation (GH-12406)

The last parameter of _Py_wreadlink(), _Py_wrealpath() and
_Py_wgetcwd() is a length, not a size: number of characters including
the trailing NUL character.

Enhance also documentation of error conditions.
This commit is contained in:
Victor Stinner 2019-03-18 17:47:26 +01:00 committed by GitHub
parent 72c7b372cf
commit 1be0d1135f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 17 deletions

View file

@ -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);

View file

@ -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];
@ -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;
}
@ -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];
@ -1700,12 +1704,13 @@ _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;
}
@ -1713,14 +1718,15 @@ _Py_wrealpath(const wchar_t *path,
/* 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;
@ -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