Commit 4c2e4fa2 authored by Victor Stinner's avatar Victor Stinner

Issue #9979: Use PyUnicode_AsWideCharString() in _ctypes module

 * Convert unicode to wide character string before creating the PyCapsule
   object
 * Catch integer overflow
 * Avoid useless memset()
 * Prepare the support of surrogates
parent b2904787
...@@ -665,24 +665,15 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) ...@@ -665,24 +665,15 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
pa->keep = obj; pa->keep = obj;
return 0; return 0;
#else #else
int size = PyUnicode_GET_SIZE(obj);
pa->ffi_type = &ffi_type_pointer; pa->ffi_type = &ffi_type_pointer;
size += 1; /* terminating NUL */ pa->value.p = PyUnicode_AsWideCharString((PyUnicodeObject *)obj, NULL);
size *= sizeof(wchar_t); if (pa->value.p == NULL)
pa->value.p = PyMem_Malloc(size);
if (!pa->value.p) {
PyErr_NoMemory();
return -1; return -1;
}
memset(pa->value.p, 0, size);
pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
if (!pa->keep) { if (!pa->keep) {
PyMem_Free(pa->value.p); PyMem_Free(pa->value.p);
return -1; return -1;
} }
if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)obj,
pa->value.p, PyUnicode_GET_SIZE(obj)))
return -1;
return 0; return 0;
#endif #endif
} }
...@@ -1147,7 +1138,7 @@ PyObject *_ctypes_callproc(PPROC pProc, ...@@ -1147,7 +1138,7 @@ PyObject *_ctypes_callproc(PPROC pProc,
} }
for (i = 0; i < argcount; ++i) { for (i = 0; i < argcount; ++i) {
atypes[i] = args[i].ffi_type; atypes[i] = args[i].ffi_type;
if (atypes[i]->type == FFI_TYPE_STRUCT if (atypes[i]->type == FFI_TYPE_STRUCT
#ifdef _WIN64 #ifdef _WIN64
&& atypes[i]->size <= sizeof(void *) && atypes[i]->size <= sizeof(void *)
#endif #endif
......
...@@ -1433,15 +1433,11 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) ...@@ -1433,15 +1433,11 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
PyObject *keep; PyObject *keep;
wchar_t *buffer; wchar_t *buffer;
int size = PyUnicode_GET_SIZE(value); buffer = PyUnicode_AsWideCharString((PyUnicodeObject *)value, NULL);
size += 1; /* terminating NUL */
size *= sizeof(wchar_t);
buffer = (wchar_t *)PyMem_Malloc(size);
if (!buffer) { if (!buffer) {
Py_DECREF(value); Py_DECREF(value);
return PyErr_NoMemory(); return NULL;
} }
memset(buffer, 0, size);
keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor); keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
if (!keep) { if (!keep) {
Py_DECREF(value); Py_DECREF(value);
...@@ -1449,12 +1445,6 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) ...@@ -1449,12 +1445,6 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size)
return NULL; return NULL;
} }
*(wchar_t **)ptr = (wchar_t *)buffer; *(wchar_t **)ptr = (wchar_t *)buffer;
if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
buffer, PyUnicode_GET_SIZE(value))) {
Py_DECREF(value);
Py_DECREF(keep);
return NULL;
}
Py_DECREF(value); Py_DECREF(value);
return keep; return keep;
} }
......
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