bpo-36346: Do not use legacy Unicode C API in ctypes. (#21429) · python/cpython@d878349
@@ -1366,8 +1366,6 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
13661366static int
13671367WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
13681368{
1369-Py_ssize_t result = 0;
1370-13711369if (value == NULL) {
13721370PyErr_SetString(PyExc_TypeError,
13731371"can't delete attribute");
@@ -1378,29 +1376,24 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored
13781376"unicode string expected instead of %s instance",
13791377Py_TYPE(value)->tp_name);
13801378return -1;
1381- } else
1382-Py_INCREF(value);
1379+ }
138313801381+Py_ssize_t size = self->b_size / sizeof(wchar_t);
13841382Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0);
13851383if (len < 0) {
13861384return -1;
13871385 }
13881386// PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
13891387// when it is called with NULL.
1390-if (((size_t)len-1) > self->b_size/sizeof(wchar_t)) {
1388+assert(len > 0);
1389+if (len - 1 > size) {
13911390PyErr_SetString(PyExc_ValueError, "string too long");
1392-result = -1;
1393- goto done;
1394- }
1395-result = PyUnicode_AsWideChar(value,
1396- (wchar_t *)self->b_ptr,
1397-self->b_size/sizeof(wchar_t));
1398-if (result >= 0 && (size_t)result < self->b_size/sizeof(wchar_t))
1399- ((wchar_t *)self->b_ptr)[result] = (wchar_t)0;
1400-done:
1401-Py_DECREF(value);
1402-1403-return result >= 0 ? 0 : -1;
1391+return -1;
1392+ }
1393+if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) {
1394+return -1;
1395+ }
1396+return 0;
14041397}
1405139814061399static PyGetSetDef WCharArray_getsets[] = {
@@ -3484,10 +3477,12 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
34843477for (i = 0; i < len; ++i) {
34853478PyObject *item = PyTuple_GET_ITEM(paramflags, i);
34863479int flag;
3487-char *name;
3480+PyObject *name = Py_None;
34883481PyObject *defval;
34893482PyObject *typ;
3490-if (!PyArg_ParseTuple(item, "i|ZO", &flag, &name, &defval)) {
3483+if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) ||
3484+ !(name == Py_None || PyUnicode_Check(name)))
3485+ {
34913486PyErr_SetString(PyExc_TypeError,
34923487"paramflags must be a sequence of (int [,string [,value]]) tuples");
34933488return 0;