Commit 37b7b82b authored by Victor Stinner's avatar Victor Stinner

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