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( PyAPI_FUNC(int) _Py_wreadlink(
const wchar_t *path, const wchar_t *path,
wchar_t *buf, wchar_t *buf,
size_t bufsiz); /* Number of characters of 'buf' buffer
including the trailing NUL character */
size_t buflen);
#endif #endif
#ifdef HAVE_REALPATH #ifdef HAVE_REALPATH
PyAPI_FUNC(wchar_t*) _Py_wrealpath( PyAPI_FUNC(wchar_t*) _Py_wrealpath(
const wchar_t *path, const wchar_t *path,
wchar_t *resolved_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 #endif
PyAPI_FUNC(wchar_t*) _Py_wgetcwd( PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
wchar_t *buf, 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); 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 #ifdef HAVE_READLINK
/* Read value of symbolic link. Encode the path to the locale encoding, decode /* 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 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 *cpath;
char cbuf[MAXPATHLEN]; char cbuf[MAXPATHLEN];
@ -1659,12 +1661,13 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
if (bufsiz <= r1) { /* wbuf must have space to store the trailing NUL character */
if (buflen <= r1) {
PyMem_RawFree(wbuf); PyMem_RawFree(wbuf);
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
wcsncpy(buf, wbuf, bufsiz); wcsncpy(buf, wbuf, buflen);
PyMem_RawFree(wbuf); PyMem_RawFree(wbuf);
return (int)r1; 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 /* Return the canonicalized absolute pathname. Encode path to the locale
encoding, decode the result from the locale encoding. 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* wchar_t*
_Py_wrealpath(const wchar_t *path, _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 *cpath;
char cresolved_path[MAXPATHLEN]; char cresolved_path[MAXPATHLEN];
@ -1700,12 +1704,13 @@ _Py_wrealpath(const wchar_t *path,
errno = EINVAL; errno = EINVAL;
return NULL; 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); PyMem_RawFree(wresolved_path);
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
wcsncpy(resolved_path, wresolved_path, resolved_path_size); wcsncpy(resolved_path, wresolved_path, resolved_path_len);
PyMem_RawFree(wresolved_path); PyMem_RawFree(wresolved_path);
return resolved_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 /* Get the current directory. size is the buffer size in wide characters
including the null character. Decode the path from the locale encoding. 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* wchar_t*
_Py_wgetcwd(wchar_t *buf, size_t size) _Py_wgetcwd(wchar_t *buf, size_t buflen)
{ {
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
int isize = (int)Py_MIN(size, INT_MAX); int ibuflen = (int)Py_MIN(buflen, INT_MAX);
return _wgetcwd(buf, isize); return _wgetcwd(buf, ibuflen);
#else #else
char fname[MAXPATHLEN]; char fname[MAXPATHLEN];
wchar_t *wname; wchar_t *wname;
@ -1731,11 +1737,12 @@ _Py_wgetcwd(wchar_t *buf, size_t size)
wname = Py_DecodeLocale(fname, &len); wname = Py_DecodeLocale(fname, &len);
if (wname == NULL) if (wname == NULL)
return NULL; return NULL;
if (size <= len) { /* wname must have space to store the trailing NUL character */
if (buflen <= len) {
PyMem_RawFree(wname); PyMem_RawFree(wname);
return NULL; return NULL;
} }
wcsncpy(buf, wname, size); wcsncpy(buf, wname, buflen);
PyMem_RawFree(wname); PyMem_RawFree(wname);
return buf; return buf;
#endif #endif