diff options
author | Victor Stinner <vstinner@redhat.com> | 2019-06-26 15:31:12 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-26 15:31:12 (GMT) |
commit | 689830ee6243126798a6c519c05aa11ba73db7cd (patch) | |
tree | 165d26fd54d4853988429c3731234cba84c6ce68 /Modules | |
parent | c6a2320e876354ee62cf8149b849bcff9492d38a (diff) | |
download | cpython-689830ee6243126798a6c519c05aa11ba73db7cd.zip cpython-689830ee6243126798a6c519c05aa11ba73db7cd.tar.gz cpython-689830ee6243126798a6c519c05aa11ba73db7cd.tar.bz2 |
bpo-37412: os.getcwdb() now uses UTF-8 on Windows (GH-14396)
The os.getcwdb() function now uses the UTF-8 encoding on Windows,
rather than the ANSI code page: see PEP 529 for the rationale. The
function is no longer deprecated on Windows.
os.getcwd() and os.getcwdb() now detect integer overflow on memory
allocations. On Unix, these functions properly report MemoryError on
memory allocation failure.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/posixmodule.c | 123 |
1 files changed, 64 insertions, 59 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 10549d6f..5134ed7 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -506,17 +506,6 @@ void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, ULONG, struct _Py_stat_struct *); #endif -#ifdef MS_WINDOWS -static int -win32_warn_bytes_api() -{ - return PyErr_WarnEx(PyExc_DeprecationWarning, - "The Windows bytes API has been deprecated, " - "use Unicode filenames instead", - 1); -} -#endif - #ifndef MS_WINDOWS PyObject * @@ -3334,83 +3323,99 @@ os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid) static PyObject * posix_getcwd(int use_bytes) { - char *buf, *tmpbuf; - char *cwd; - const size_t chunk = 1024; - size_t buflen = 0; - PyObject *obj; - #ifdef MS_WINDOWS - if (!use_bytes) { - wchar_t wbuf[MAXPATHLEN]; - wchar_t *wbuf2 = wbuf; - PyObject *resobj; - DWORD len; - Py_BEGIN_ALLOW_THREADS - len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); - /* If the buffer is large enough, len does not include the - terminating \0. If the buffer is too small, len includes - the space needed for the terminator. */ - if (len >= Py_ARRAY_LENGTH(wbuf)) { + wchar_t wbuf[MAXPATHLEN]; + wchar_t *wbuf2 = wbuf; + DWORD len; + + Py_BEGIN_ALLOW_THREADS + len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); + /* If the buffer is large enough, len does not include the + terminating \0. If the buffer is too small, len includes + the space needed for the terminator. */ + if (len >= Py_ARRAY_LENGTH(wbuf)) { + if (len >= PY_SSIZE_T_MAX / sizeof(wchar_t)) { wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); - if (wbuf2) - len = GetCurrentDirectoryW(len, wbuf2); } - Py_END_ALLOW_THREADS - if (!wbuf2) { - PyErr_NoMemory(); - return NULL; + else { + wbuf2 = NULL; } - if (!len) { - if (wbuf2 != wbuf) - PyMem_RawFree(wbuf2); - return PyErr_SetFromWindowsErr(0); + if (wbuf2) { + len = GetCurrentDirectoryW(len, wbuf2); } - resobj = PyUnicode_FromWideChar(wbuf2, len); + } + Py_END_ALLOW_THREADS + + if (!wbuf2) { + PyErr_NoMemory(); + return NULL; + } + if (!len) { if (wbuf2 != wbuf) PyMem_RawFree(wbuf2); - return resobj; + return PyErr_SetFromWindowsErr(0); } - if (win32_warn_bytes_api()) - return NULL; -#endif + PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); + if (wbuf2 != wbuf) { + PyMem_RawFree(wbuf2); + } + + if (use_bytes) { + if (resobj == NULL) { + return NULL; + } + Py_SETREF(resobj, PyUnicode_EncodeFSDefault(resobj)); + } + + return resobj; +#else + const size_t chunk = 1024; + + char *buf = NULL; + char *cwd = NULL; + size_t buflen = 0; - buf = cwd = NULL; Py_BEGIN_ALLOW_THREADS do { - buflen += chunk; -#ifdef MS_WINDOWS - if (buflen > INT_MAX) { - PyErr_NoMemory(); - break; + char *newbuf; + if (buflen <= PY_SSIZE_T_MAX - chunk) { + buflen += chunk; + newbuf = PyMem_RawRealloc(buf, buflen); } -#endif - tmpbuf = PyMem_RawRealloc(buf, buflen); - if (tmpbuf == NULL) + else { + newbuf = NULL; + } + if (newbuf == NULL) { + PyMem_RawFree(buf); + buf = NULL; break; + } + buf = newbuf; - buf = tmpbuf; -#ifdef MS_WINDOWS - cwd = getcwd(buf, (int)buflen); -#else cwd = getcwd(buf, buflen); -#endif } while (cwd == NULL && errno == ERANGE); Py_END_ALLOW_THREADS + if (buf == NULL) { + return PyErr_NoMemory(); + } if (cwd == NULL) { PyMem_RawFree(buf); return posix_error(); } - if (use_bytes) + PyObject *obj; + if (use_bytes) { obj = PyBytes_FromStringAndSize(buf, strlen(buf)); - else + } + else { obj = PyUnicode_DecodeFSDefault(buf); + } PyMem_RawFree(buf); return obj; +#endif /* !MS_WINDOWS */ } |