bpo-36346: Do not use legacy Unicode C API in ctypes. (#21429)
This commit is contained in:
parent
0f9aa47bab
commit
d878349bac
|
@ -1366,8 +1366,6 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
|
||||||
static int
|
static int
|
||||||
WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
|
WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
Py_ssize_t result = 0;
|
|
||||||
|
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"can't delete attribute");
|
"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",
|
"unicode string expected instead of %s instance",
|
||||||
Py_TYPE(value)->tp_name);
|
Py_TYPE(value)->tp_name);
|
||||||
return -1;
|
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);
|
Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
|
// PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
|
||||||
// when it is called with NULL.
|
// 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");
|
PyErr_SetString(PyExc_ValueError, "string too long");
|
||||||
result = -1;
|
return -1;
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
result = PyUnicode_AsWideChar(value,
|
if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) {
|
||||||
(wchar_t *)self->b_ptr,
|
return -1;
|
||||||
self->b_size/sizeof(wchar_t));
|
}
|
||||||
if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
|
return 0;
|
||||||
((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
|
|
||||||
done:
|
|
||||||
Py_DECREF(value);
|
|
||||||
|
|
||||||
return result >= 0 ? 0 : -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyGetSetDef WCharArray_getsets[] = {
|
static PyGetSetDef WCharArray_getsets[] = {
|
||||||
|
@ -3484,10 +3477,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
PyObject *item = PyTuple_GET_ITEM(paramflags, i);
|
PyObject *item = PyTuple_GET_ITEM(paramflags, i);
|
||||||
int flag;
|
int flag;
|
||||||
char *name;
|
PyObject *name = Py_None;
|
||||||
PyObject *defval;
|
PyObject *defval;
|
||||||
PyObject *typ;
|
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,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"paramflags must be a sequence of (int [,string [,value]]) tuples");
|
"paramflags must be a sequence of (int [,string [,value]]) tuples");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1300,7 +1300,6 @@ module. load_flags are as defined for LoadLibraryEx in the\n\
|
||||||
Windows API.\n";
|
Windows API.\n";
|
||||||
static PyObject *load_library(PyObject *self, PyObject *args)
|
static PyObject *load_library(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
const WCHAR *name;
|
|
||||||
PyObject *nameobj;
|
PyObject *nameobj;
|
||||||
int load_flags = 0;
|
int load_flags = 0;
|
||||||
HMODULE hMod;
|
HMODULE hMod;
|
||||||
|
@ -1309,14 +1308,14 @@ static PyObject *load_library(PyObject *self, PyObject *args)
|
||||||
if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags))
|
if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
name = _PyUnicode_AsUnicode(nameobj);
|
|
||||||
if (!name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) {
|
if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WCHAR *name = PyUnicode_AsWideCharString(nameobj, NULL);
|
||||||
|
if (!name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
/* bpo-36085: Limit DLL search directories to avoid pre-loading
|
/* bpo-36085: Limit DLL search directories to avoid pre-loading
|
||||||
* attacks and enable use of the AddDllDirectory function.
|
* attacks and enable use of the AddDllDirectory function.
|
||||||
|
@ -1325,6 +1324,7 @@ static PyObject *load_library(PyObject *self, PyObject *args)
|
||||||
err = hMod ? 0 : GetLastError();
|
err = hMod ? 0 : GetLastError();
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
|
PyMem_Free(name);
|
||||||
if (err == ERROR_MOD_NOT_FOUND) {
|
if (err == ERROR_MOD_NOT_FOUND) {
|
||||||
PyErr_Format(PyExc_FileNotFoundError,
|
PyErr_Format(PyExc_FileNotFoundError,
|
||||||
("Could not find module '%.500S' (or one of its "
|
("Could not find module '%.500S' (or one of its "
|
||||||
|
|
|
@ -1220,11 +1220,8 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length)
|
||||||
"string too long (%zd, maximum length %zd)",
|
"string too long (%zd, maximum length %zd)",
|
||||||
size, length);
|
size, length);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (size < length-1)
|
}
|
||||||
/* copy terminating NUL character if there is space */
|
if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, length) == -1) {
|
||||||
size += 1;
|
|
||||||
|
|
||||||
if (PyUnicode_AsWideChar(value, (wchar_t *)ptr, size) == -1) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue