posix module catches PyUnicode_AsUnicode() failure
* Replace PyUnicode_AS_UNICODE by PyUnicode_AsUnicode, PyUnicode_AS_UNICODE is
no more a real macro
* Replace Py_UNICODE by wchar_t in code specific to Windows
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index c35e8a1..094ceb7 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -697,7 +697,7 @@
}
static PyObject *
-win32_error_unicode(char* function, Py_UNICODE* filename)
+win32_error_unicode(char* function, wchar_t* filename)
{
/* XXX - see win32_error for comments on 'function' */
errno = GetLastError();
@@ -707,6 +707,20 @@
return PyErr_SetFromWindowsErr(errno);
}
+static PyObject *
+win32_error_object(char* function, PyObject* filename)
+{
+ /* XXX - see win32_error for comments on 'function' */
+ errno = GetLastError();
+ if (filename)
+ return PyErr_SetExcFromWindowsErrWithFilenameObject(
+ PyExc_WindowsError,
+ errno,
+ filename);
+ else
+ return PyErr_SetFromWindowsErr(errno);
+}
+
static int
convert_to_unicode(PyObject **param)
{
@@ -881,17 +895,21 @@
char *ansi;
BOOL result;
- if (!PyArg_ParseTuple(args, wformat, &uni))
- PyErr_Clear();
- else {
+ if (PyArg_ParseTuple(args, wformat, &uni))
+ {
+ wchar_t *wstr = PyUnicode_AsUnicode(uni);
+ if (wstr == NULL)
+ return NULL;
Py_BEGIN_ALLOW_THREADS
- result = funcW(PyUnicode_AsUnicode(uni));
+ result = funcW(wstr);
Py_END_ALLOW_THREADS
if (!result)
- return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
+ return win32_error_object(func, uni);
Py_INCREF(Py_None);
return Py_None;
}
+ PyErr_Clear();
+
if (!PyArg_ParseTuple(args, format, &ansi))
return NULL;
Py_BEGIN_ALLOW_THREADS
@@ -1801,7 +1819,7 @@
int (*statfunc)(const char *, STRUCT_STAT *),
#endif
char *wformat,
- int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
+ int (*wstatfunc)(const wchar_t *, STRUCT_STAT *))
{
STRUCT_STAT st;
PyObject *opath;
@@ -1810,18 +1828,18 @@
PyObject *result;
#ifdef MS_WINDOWS
- PyUnicodeObject *po;
+ PyObject *po;
if (PyArg_ParseTuple(args, wformat, &po)) {
- Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
+ wchar_t *wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE result OK without
- thread lock as it is a simple dereference. */
res = wstatfunc(wpath, &st);
Py_END_ALLOW_THREADS
if (res != 0)
- return win32_error_unicode("stat", wpath);
+ return win32_error_object("stat", po);
return _pystat_fromstructstat(&st);
}
/* Drop the argument parsing error as narrow strings
@@ -1870,12 +1888,13 @@
#ifdef MS_WINDOWS
DWORD attr;
- PyUnicodeObject *po;
+ PyObject *po;
if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
+ wchar_t* wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread lock as
- it is a simple dereference. */
- attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+ attr = GetFileAttributesW(wpath);
Py_END_ALLOW_THREADS
goto finish;
}
@@ -2025,23 +2044,25 @@
int res;
#ifdef MS_WINDOWS
DWORD attr;
- PyUnicodeObject *po;
+ PyObject *po;
if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
+ wchar_t *wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
Py_BEGIN_ALLOW_THREADS
- attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
+ attr = GetFileAttributesW(wpath);
if (attr != 0xFFFFFFFF) {
if (i & _S_IWRITE)
attr &= ~FILE_ATTRIBUTE_READONLY;
else
attr |= FILE_ATTRIBUTE_READONLY;
- res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
+ res = SetFileAttributesW(wpath, attr);
}
else
res = 0;
Py_END_ALLOW_THREADS
if (!res)
- return win32_error_unicode("chmod",
- PyUnicode_AS_UNICODE(po));
+ return win32_error_object("chmod", po);
Py_INCREF(Py_None);
return Py_None;
}
@@ -2429,12 +2450,20 @@
PyObject *osrc, *odst;
char *src, *dst;
BOOL rslt;
+ PyObject *usrc, *udst;
- PyUnicodeObject *usrc, *udst;
- if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) {
+ if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst))
+ {
+ wchar_t *wsrc, *wdst;
+ wsrc = PyUnicode_AsUnicode(usrc);
+ if (wsrc == NULL)
+ return NULL;
+ wdst = PyUnicode_AsUnicode(udst);
+ if (wdst == NULL)
+ return NULL;
+
Py_BEGIN_ALLOW_THREADS
- rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst),
- PyUnicode_AS_UNICODE(usrc), NULL);
+ rslt = CreateHardLinkW(wdst, wsrc, NULL);
Py_END_ALLOW_THREADS
if (rslt == 0)
@@ -2495,13 +2524,15 @@
PyObject *po = NULL;
if (PyArg_ParseTuple(args, "|U:listdir", &po)) {
WIN32_FIND_DATAW wFileData;
- Py_UNICODE *wnamebuf, *po_wchars;
+ wchar_t *wnamebuf, *po_wchars;
if (po == NULL) { /* Default arg: "." */
po_wchars = L".";
len = 1;
} else {
- po_wchars = PyUnicode_AS_UNICODE(po);
+ po_wchars = PyUnicode_AsUnicode(po);
+ if (po_wchars == NULL)
+ return NULL;
len = PyUnicode_GET_SIZE(po);
}
/* Overallocate for \\*.*\0 */
@@ -2512,7 +2543,7 @@
}
wcscpy(wnamebuf, po_wchars);
if (len > 0) {
- Py_UNICODE wch = wnamebuf[len-1];
+ wchar_t wch = wnamebuf[len-1];
if (wch != L'/' && wch != L'\\' && wch != L':')
wnamebuf[len++] = L'\\';
wcscpy(wnamebuf + len, L"*.*");
@@ -2887,18 +2918,24 @@
char outbuf[MAX_PATH*2];
char *temp;
#ifdef MS_WINDOWS
- PyUnicodeObject *po;
- if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
- Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
- Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
- Py_UNICODE *wtemp;
+ PyObject *po;
+
+ if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
+ {
+ wchar_t *wpath;
+ wchar_t woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
+ wchar_t *wtemp;
DWORD result;
PyObject *v;
+
+ wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
result = GetFullPathNameW(wpath,
Py_ARRAY_LENGTH(woutbuf),
woutbuf, &wtemp);
if (result > Py_ARRAY_LENGTH(woutbuf)) {
- woutbufp = malloc(result * sizeof(Py_UNICODE));
+ woutbufp = malloc(result * sizeof(wchar_t));
if (!woutbufp)
return PyErr_NoMemory();
result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
@@ -2906,7 +2943,7 @@
if (result)
v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
else
- v = win32_error_unicode("GetFullPathNameW", wpath);
+ v = win32_error_object("GetFullPathNameW", po);
if (woutbufp != woutbuf)
free(woutbufp);
return v;
@@ -2914,8 +2951,8 @@
/* Drop the argument parsing error as narrow strings
are also valid. */
PyErr_Clear();
-
#endif
+
if (!PyArg_ParseTuple (args, "O&:_getfullpathname",
PyUnicode_FSConverter, &opath))
return NULL;
@@ -2944,12 +2981,14 @@
int buf_size;
wchar_t *target_path;
int result_length;
- PyObject *result;
+ PyObject *po, *result;
wchar_t *path;
- if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) {
+ if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po))
return NULL;
- }
+ path = PyUnicode_AsUnicode(po);
+ if (path == NULL)
+ return NULL;
if(!check_GetFinalPathNameByHandle()) {
/* If the OS doesn't have GetFinalPathNameByHandle, return a
@@ -2968,18 +3007,15 @@
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
- if(hFile == INVALID_HANDLE_VALUE) {
- return win32_error_unicode("GetFinalPathNamyByHandle", path);
- return PyErr_Format(PyExc_RuntimeError,
- "Could not get a handle to file.");
- }
+ if(hFile == INVALID_HANDLE_VALUE)
+ return win32_error_object("CreateFileW", po);
/* We have a good handle to the target, use it to determine the
target path name. */
buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
if(!buf_size)
- return win32_error_unicode("GetFinalPathNameByHandle", path);
+ return win32_error_object("GetFinalPathNameByHandle", po);
target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t));
if(!target_path)
@@ -2988,10 +3024,10 @@
result_length = Py_GetFinalPathNameByHandleW(hFile, target_path,
buf_size, VOLUME_NAME_DOS);
if(!result_length)
- return win32_error_unicode("GetFinalPathNamyByHandle", path);
+ return win32_error_object("GetFinalPathNamyByHandle", po);
if(!CloseHandle(hFile))
- return win32_error_unicode("GetFinalPathNameByHandle", path);
+ return win32_error_object("CloseHandle", po);
target_path[result_length] = 0;
result = PyUnicode_FromUnicode(target_path, result_length);
@@ -3033,11 +3069,13 @@
{
PyObject *opath;
char *path;
- PyUnicodeObject *po;
+ PyObject *po;
DWORD attributes;
if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
- Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
+ wchar_t *wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
attributes = GetFileAttributesW(wpath);
if (attributes == INVALID_FILE_ATTRIBUTES)
@@ -3078,15 +3116,18 @@
int mode = 0777;
#ifdef MS_WINDOWS
- PyUnicodeObject *po;
- if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
+ PyObject *po;
+ if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode))
+ {
+ wchar_t *wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
+
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread lock as
- it is a simple dereference. */
- res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
+ res = CreateDirectoryW(wpath, NULL);
Py_END_ALLOW_THREADS
if (!res)
- return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
+ return win32_error_object("mkdir", po);
Py_INCREF(Py_None);
return Py_None;
}
@@ -3098,8 +3139,6 @@
return NULL;
path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread lock as
- it is a simple dereference. */
res = CreateDirectoryA(path, NULL);
Py_END_ALLOW_THREADS
if (!res) {
@@ -3225,6 +3264,7 @@
{
#ifdef MS_WINDOWS
PyObject *o1, *o2;
+ wchar_t *w1, *w2;
char *p1, *p2;
BOOL result;
if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
@@ -3235,9 +3275,14 @@
Py_DECREF(o1);
goto error;
}
+ w1 = PyUnicode_AsUnicode(o1);
+ if (w1 == NULL)
+ goto error;
+ w2 = PyUnicode_AsUnicode(o2);
+ if (w2 == NULL)
+ goto error;
Py_BEGIN_ALLOW_THREADS
- result = MoveFileW(PyUnicode_AsUnicode(o1),
- PyUnicode_AsUnicode(o2));
+ result = MoveFileW(w1, w2);
Py_END_ALLOW_THREADS
Py_DECREF(o1);
Py_DECREF(o2);
@@ -3497,7 +3542,7 @@
{
#ifdef MS_WINDOWS
PyObject *arg;
- PyUnicodeObject *obwpath;
+ PyObject *obwpath;
wchar_t *wpath = NULL;
PyObject *oapath;
char *apath;
@@ -3508,23 +3553,26 @@
PyObject *result = NULL;
if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
- wpath = PyUnicode_AS_UNICODE(obwpath);
+ wpath = PyUnicode_AsUnicode(obwpath);
+ if (wpath == NULL)
+ return NULL;
Py_BEGIN_ALLOW_THREADS
hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
Py_END_ALLOW_THREADS
if (hFile == INVALID_HANDLE_VALUE)
- return win32_error_unicode("utime", wpath);
- } else
+ return win32_error_object("utime", obwpath);
+ }
+ else {
/* Drop the argument parsing error as narrow strings
are also valid. */
PyErr_Clear();
- if (!wpath) {
if (!PyArg_ParseTuple(args, "O&O:utime",
PyUnicode_FSConverter, &oapath, &arg))
return NULL;
+
apath = PyBytes_AsString(oapath);
Py_BEGIN_ALLOW_THREADS
hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
@@ -6372,7 +6420,7 @@
wchar_t *path;
DWORD n_bytes_returned;
DWORD io_result;
- PyObject *result;
+ PyObject *po, *result;
HANDLE reparse_point_handle;
char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
@@ -6380,8 +6428,11 @@
wchar_t *print_name;
if (!PyArg_ParseTuple(args,
- "u:readlink",
- &path))
+ "U:readlink",
+ &po))
+ return NULL;
+ path = PyUnicode_AsUnicode(po);
+ if (path == NULL)
return NULL;
/* First get a handle to the reparse point */
@@ -6397,9 +6448,7 @@
Py_END_ALLOW_THREADS
if (reparse_point_handle==INVALID_HANDLE_VALUE)
- {
- return win32_error_unicode("readlink", path);
- }
+ return win32_error_object("readlink", po);
Py_BEGIN_ALLOW_THREADS
/* New call DeviceIoControl to read the reparse point */
@@ -6415,9 +6464,7 @@
Py_END_ALLOW_THREADS
if (io_result==0)
- {
- return win32_error_unicode("readlink", path);
- }
+ return win32_error_object("readlink", po);
if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
{
@@ -6468,6 +6515,7 @@
{
static char *kwlist[] = {"src", "dest", "target_is_directory", NULL};
PyObject *src, *dest;
+ wchar_t *wsrc, *wdest;
int target_is_directory = 0;
DWORD res;
WIN32_FILE_ATTRIBUTE_DATA src_info;
@@ -6485,16 +6533,24 @@
if (win32_can_symlink == 0)
return PyErr_Format(PyExc_OSError, "symbolic link privilege not held");
- if (!convert_to_unicode(&src)) { return NULL; }
+ if (!convert_to_unicode(&src))
+ return NULL;
if (!convert_to_unicode(&dest)) {
Py_DECREF(src);
return NULL;
}
+ wsrc = PyUnicode_AsUnicode(src);
+ if (wsrc == NULL)
+ goto error;
+ wdest = PyUnicode_AsUnicode(dest);
+ if (wsrc == NULL)
+ goto error;
+
/* if src is a directory, ensure target_is_directory==1 */
if(
GetFileAttributesExW(
- PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info
+ wsrc, GetFileExInfoStandard, &src_info
))
{
target_is_directory = target_is_directory ||
@@ -6502,20 +6558,21 @@
}
Py_BEGIN_ALLOW_THREADS
- res = Py_CreateSymbolicLinkW(
- PyUnicode_AsUnicode(dest),
- PyUnicode_AsUnicode(src),
- target_is_directory);
+ res = Py_CreateSymbolicLinkW(wdest, wsrc, target_is_directory);
Py_END_ALLOW_THREADS
+
Py_DECREF(src);
Py_DECREF(dest);
if (!res)
- {
- return win32_error_unicode("symlink", PyUnicode_AsUnicode(src));
- }
+ return win32_error_object("symlink", src);
Py_INCREF(Py_None);
return Py_None;
+
+error:
+ Py_DECREF(src);
+ Py_DECREF(dest);
+ return NULL;
}
#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
@@ -6710,12 +6767,14 @@
int fd;
#ifdef MS_WINDOWS
- PyUnicodeObject *po;
+ PyObject *po;
if (PyArg_ParseTuple(args, "Ui|i:open", &po, &flag, &mode)) {
+ wchar_t *wpath = PyUnicode_AsUnicode(po);
+ if (wpath == NULL)
+ return NULL;
+
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread
- lock as it is a simple dereference. */
- fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
+ fd = _wopen(wpath, flag, mode);
Py_END_ALLOW_THREADS
if (fd < 0)
return posix_error();
@@ -7717,6 +7776,8 @@
}
#ifdef MS_WINDOWS
newenv = PyUnicode_AsUnicode(newstr);
+ if (newenv == NULL)
+ goto error;
_snwprintf(newenv, len, L"%s=%s", s1, s2);
if (_wputenv(newenv)) {
posix_error();
@@ -9178,9 +9239,10 @@
PyObject *ofilepath;
char *filepath;
char *operation = NULL;
+ wchar_t *wpath, *woperation;
HINSTANCE rc;
- PyObject *unipath, *woperation = NULL;
+ PyObject *unipath, *uoperation = NULL;
if (!PyArg_ParseTuple(args, "U|s:startfile",
&unipath, &operation)) {
PyErr_Clear();
@@ -9188,26 +9250,35 @@
}
if (operation) {
- woperation = PyUnicode_DecodeASCII(operation,
+ uoperation = PyUnicode_DecodeASCII(operation,
strlen(operation), NULL);
- if (!woperation) {
+ if (!uoperation) {
PyErr_Clear();
operation = NULL;
goto normal;
}
}
+ wpath = PyUnicode_AsUnicode(unipath);
+ if (wpath == NULL)
+ goto normal;
+ if (uoperation) {
+ woperation = PyUnicode_AsUnicode(uoperation);
+ if (woperation == NULL)
+ goto normal;
+ }
+ else
+ woperation = NULL;
+
Py_BEGIN_ALLOW_THREADS
- rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
- PyUnicode_AS_UNICODE(unipath),
- NULL, NULL, SW_SHOWNORMAL);
+ rc = ShellExecuteW((HWND)0, woperation, wpath,
+ NULL, NULL, SW_SHOWNORMAL);
Py_END_ALLOW_THREADS
- Py_XDECREF(woperation);
+ Py_XDECREF(uoperation);
if (rc <= (HINSTANCE)32) {
- PyObject *errval = win32_error_unicode("startfile",
- PyUnicode_AS_UNICODE(unipath));
- return errval;
+ win32_error_object("startfile", unipath);
+ return NULL;
}
Py_INCREF(Py_None);
return Py_None;