diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index ceae67ebb16..0ac48b92bff 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1366,8 +1366,6 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored)) static int WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)) { - Py_ssize_t result = 0; - if (value == NULL) { PyErr_SetString(PyExc_TypeError, "can't delete attribute"); @@ -1378,29 +1376,24 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored "unicode string expected instead of %s instance", Py_TYPE(value)->tp_name); return -1; - } else - Py_INCREF(value); + } + Py_ssize_t size = self->b_size / sizeof(wchar_t); Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0); if (len < 0) { return -1; } // PyUnicode_AsWideChar() returns number of wchars including trailing null byte, // when it is called with NULL. - if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) { + assert(len > 0); + if (len - 1 > size) { PyErr_SetString(PyExc_ValueError, "string too long"); - result = -1; - goto done; + return -1; } - result = PyUnicode_AsWideChar(value, - (wchar_t *)self->b_ptr, - self->b_size/sizeof(wchar_t)); - if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t)) - ((wchar_t *)self->b_ptr)[result] = (wchar_t)0; - done: - Py_DECREF(value); - - return result >= 0 ? 0 : -1; + if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) { + return -1; + } + return 0; } static PyGetSetDef WCharArray_getsets[] = { @@ -3484,10 +3477,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags) for (i = 0; i < len; ++i) { PyObject *item = PyTuple_GET_ITEM(paramflags, i); int flag; - char *name; + PyObject *name = Py_None; PyObject *defval; PyObject *typ; - if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) { + if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) || + !(name == Py_None || PyUnicode_Check(name))) + { PyErr_SetString(PyExc_TypeError, "paramflags must be a sequence of (int [,string [,value]]) tuples"); return 0; diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 6030cc3d436..261ae5ceb9e 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1300,7 +1300,6 @@ module. load_flags are as defined for LoadLibraryEx in the\n\ Windows API.\n"; static PyObject *load_library(PyObject *self, PyObject *args) { - const WCHAR *name; PyObject *nameobj; int load_flags = 0; HMODULE hMod; @@ -1309,14 +1308,14 @@ static PyObject *load_library(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags)) return NULL; - name = _PyUnicode_AsUnicode(nameobj); - if (!name) - return NULL; - if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) { return NULL; } + WCHAR *name = PyUnicode_AsWideCharString(nameobj, NULL); + if (!name) + return NULL; + Py_BEGIN_ALLOW_THREADS /* bpo-36085: Limit DLL search directories to avoid pre-loading * attacks and enable use of the AddDllDirectory function. @@ -1325,6 +1324,7 @@ static PyObject *load_library(PyObject *self, PyObject *args) err = hMod ? 0 : GetLastError(); Py_END_ALLOW_THREADS + PyMem_Free(name); if (err == ERROR_MOD_NOT_FOUND) { PyErr_Format(PyExc_FileNotFoundError, ("Could not find module '%.500S' (or one of its " diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 3a9b7119201..3bd9ae438db 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1220,11 +1220,8 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) "string too long (%zd, maximum length %zd)", size, length); return NULL; - } else if (size < length-1) - /* copy terminating NUL character if there is space */ - size += 1; - - if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) { + } + if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) { return NULL; }