• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   ToDo:
3 
4   Get rid of the checker (and also the converters) field in PyCFuncPtrObject and
5   StgInfo, and replace them by slot functions in StgInfo.
6 
7   think about a buffer-like object (memory? bytes?)
8 
9   Should POINTER(c_char) and POINTER(c_wchar) have a .value property?
10   What about c_char and c_wchar arrays then?
11 
12   Add from_mmap, from_file, from_string metaclass methods.
13 
14   Maybe we can get away with from_file (calls read) and with a from_buffer
15   method?
16 
17   And what about the to_mmap, to_file, to_str(?) methods?  They would clobber
18   the namespace, probably. So, functions instead? And we already have memmove...
19 */
20 
21 /*
22 
23 Name                    methods, members, getsets
24 ==============================================================================
25 
26 PyCStructType_Type              __new__(), from_address(), __mul__(), from_param()
27 UnionType_Type                  __new__(), from_address(), __mul__(), from_param()
28 PyCPointerType_Type             __new__(), from_address(), __mul__(), from_param(), set_type()
29 PyCArrayType_Type               __new__(), from_address(), __mul__(), from_param()
30 PyCSimpleType_Type              __new__(), from_address(), __mul__(), from_param()
31 
32 PyCData_Type
33   Struct_Type                   __new__(), __init__()
34   PyCPointer_Type               __new__(), __init__(), _as_parameter_, contents
35   PyCArray_Type                 __new__(), __init__(), _as_parameter_, __get/setitem__(), __len__()
36   Simple_Type                   __new__(), __init__(), _as_parameter_
37 
38 PyCField_Type
39 
40 ==============================================================================
41 
42 class methods
43 -------------
44 
45 It has some similarity to the byref() construct compared to pointer()
46 from_address(addr)
47     - construct an instance from a given memory block (sharing this memory block)
48 
49 from_param(obj)
50     - typecheck and convert a Python object into a C function call parameter
51       The result may be an instance of the type, or an integer or tuple
52       (typecode, value[, obj])
53 
54 instance methods/properties
55 ---------------------------
56 
57 _as_parameter_
58     - convert self into a C function call parameter
59       This is either an integer, or a 3-tuple (typecode, value, obj)
60 
61 functions
62 ---------
63 
64 sizeof(cdata)
65     - return the number of bytes the buffer contains
66 
67 sizeof(ctype)
68     - return the number of bytes the buffer of an instance would contain
69 
70 byref(cdata)
71 
72 addressof(cdata)
73 
74 pointer(cdata)
75 
76 POINTER(ctype)
77 
78 bytes(cdata)
79     - return the buffer contents as a sequence of bytes (which is currently a string)
80 
81 */
82 
83 /*
84  * PyCStructType_Type
85  * UnionType_Type
86  * PyCPointerType_Type
87  * PyCArrayType_Type
88  * PyCSimpleType_Type
89  *
90  * PyCData_Type
91  * Struct_Type
92  * Union_Type
93  * PyCArray_Type
94  * Simple_Type
95  * PyCPointer_Type
96  * PyCField_Type
97  *
98  */
99 #ifndef Py_BUILD_CORE_BUILTIN
100 #  define Py_BUILD_CORE_MODULE 1
101 #endif
102 
103 #include "Python.h"
104 // windows.h must be included before pycore internal headers
105 #ifdef MS_WIN32
106 #  include <windows.h>
107 #endif
108 
109 #include "pycore_call.h"          // _PyObject_CallNoArgs()
110 #include "pycore_ceval.h"         // _Py_EnterRecursiveCall()
111 #ifdef MS_WIN32
112 #  include "pycore_modsupport.h"  // _PyArg_NoKeywords()
113 #endif
114 
115 
116 #include <ffi.h>
117 #ifdef MS_WIN32
118 #include <malloc.h>
119 #ifndef IS_INTRESOURCE
120 #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
121 #endif
122 #else
123 #include <dlfcn.h>
124 #endif
125 #include "ctypes.h"
126 
127 #include "pycore_long.h"          // _PyLong_GetZero()
128 
129 /*[clinic input]
130 module _ctypes
131 [clinic start generated code]*/
132 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=476a19c49b31a75c]*/
133 
134 #define clinic_state() (get_module_state_by_class(cls))
135 #define clinic_state_sub() (get_module_state_by_class(cls->tp_base))
136 #include "clinic/_ctypes.c.h"
137 #undef clinic_state
138 #undef clinic_state_sub
139 
140 /****************************************************************/
141 
142 typedef struct {
143     PyObject_HEAD
144     PyObject *key;
145     PyObject *dict;
146 } DictRemoverObject;
147 
148 static int
_DictRemover_traverse(DictRemoverObject * self,visitproc visit,void * arg)149 _DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
150 {
151     Py_VISIT(Py_TYPE(self));
152     Py_VISIT(self->key);
153     Py_VISIT(self->dict);
154     return 0;
155 }
156 
157 static int
_DictRemover_clear(DictRemoverObject * self)158 _DictRemover_clear(DictRemoverObject *self)
159 {
160     Py_CLEAR(self->key);
161     Py_CLEAR(self->dict);
162     return 0;
163 }
164 
165 static void
_DictRemover_dealloc(PyObject * myself)166 _DictRemover_dealloc(PyObject *myself)
167 {
168     PyTypeObject *tp = Py_TYPE(myself);
169     DictRemoverObject *self = (DictRemoverObject *)myself;
170     PyObject_GC_UnTrack(myself);
171     (void)_DictRemover_clear(self);
172     tp->tp_free(myself);
173     Py_DECREF(tp);
174 }
175 
176 static PyObject *
_DictRemover_call(PyObject * myself,PyObject * args,PyObject * kw)177 _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
178 {
179     DictRemoverObject *self = (DictRemoverObject *)myself;
180     if (self->key && self->dict) {
181         if (-1 == PyDict_DelItem(self->dict, self->key)) {
182             PyErr_FormatUnraisable("Exception ignored on calling _ctypes.DictRemover");
183         }
184         Py_CLEAR(self->key);
185         Py_CLEAR(self->dict);
186     }
187     Py_RETURN_NONE;
188 }
189 
190 PyDoc_STRVAR(dictremover_doc, "deletes a key from a dictionary");
191 
192 static PyType_Slot dictremover_slots[] = {
193     {Py_tp_dealloc, _DictRemover_dealloc},
194     {Py_tp_traverse, _DictRemover_traverse},
195     {Py_tp_clear, _DictRemover_clear},
196     {Py_tp_call, _DictRemover_call},
197     {Py_tp_doc, (void *)dictremover_doc},
198     {0, NULL},
199 };
200 
201 static PyType_Spec dictremover_spec = {
202     .name = "_ctypes.DictRemover",
203     .basicsize = sizeof(DictRemoverObject),
204     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
205               Py_TPFLAGS_IMMUTABLETYPE),
206     .slots = dictremover_slots,
207 };
208 
209 int
PyDict_SetItemProxy(ctypes_state * st,PyObject * dict,PyObject * key,PyObject * item)210 PyDict_SetItemProxy(ctypes_state *st, PyObject *dict, PyObject *key, PyObject *item)
211 {
212     PyObject *obj;
213     DictRemoverObject *remover;
214     PyObject *proxy;
215     int result;
216 
217     obj = _PyObject_CallNoArgs((PyObject *)st->DictRemover_Type);
218     if (obj == NULL)
219         return -1;
220 
221     remover = (DictRemoverObject *)obj;
222     assert(remover->key == NULL);
223     assert(remover->dict == NULL);
224     remover->key = Py_NewRef(key);
225     remover->dict = Py_NewRef(dict);
226 
227     proxy = PyWeakref_NewProxy(item, obj);
228     Py_DECREF(obj);
229     if (proxy == NULL)
230         return -1;
231 
232     result = PyDict_SetItem(dict, key, proxy);
233     Py_DECREF(proxy);
234     return result;
235 }
236 
237 static int
_PyDict_GetItemProxy(PyObject * dict,PyObject * key,PyObject ** presult)238 _PyDict_GetItemProxy(PyObject *dict, PyObject *key, PyObject **presult)
239 {
240     int rc = PyDict_GetItemRef(dict, key, presult);
241     PyObject *item = *presult;
242     if (item && PyWeakref_CheckProxy(item)) {
243         rc = PyWeakref_GetRef(item, presult);
244         Py_DECREF(item);
245     }
246     return rc;
247 }
248 
249 /******************************************************************/
250 
251 /*
252   Allocate a memory block for a pep3118 format string, filled with
253   a suitable PEP 3118 type code corresponding to the given ctypes
254   type. Returns NULL on failure, with the error indicator set.
255 
256   This produces type codes in the standard size mode (cf. struct module),
257   since the endianness may need to be swapped to a non-native one
258   later on.
259  */
260 static char *
_ctypes_alloc_format_string_for_type(char code,int big_endian)261 _ctypes_alloc_format_string_for_type(char code, int big_endian)
262 {
263     char *result;
264     char pep_code = '\0';
265 
266     switch (code) {
267 #if SIZEOF_INT == 2
268     case 'i': pep_code = 'h'; break;
269     case 'I': pep_code = 'H'; break;
270 #elif SIZEOF_INT == 4
271     case 'i': pep_code = 'i'; break;
272     case 'I': pep_code = 'I'; break;
273 #elif SIZEOF_INT == 8
274     case 'i': pep_code = 'q'; break;
275     case 'I': pep_code = 'Q'; break;
276 #else
277 # error SIZEOF_INT has an unexpected value
278 #endif /* SIZEOF_INT */
279 #if SIZEOF_LONG == 4
280     case 'l': pep_code = 'l'; break;
281     case 'L': pep_code = 'L'; break;
282 #elif SIZEOF_LONG == 8
283     case 'l': pep_code = 'q'; break;
284     case 'L': pep_code = 'Q'; break;
285 #else
286 # error SIZEOF_LONG has an unexpected value
287 #endif /* SIZEOF_LONG */
288 #if SIZEOF__BOOL == 1
289     case '?': pep_code = '?'; break;
290 #elif SIZEOF__BOOL == 2
291     case '?': pep_code = 'H'; break;
292 #elif SIZEOF__BOOL == 4
293     case '?': pep_code = 'L'; break;
294 #elif SIZEOF__BOOL == 8
295     case '?': pep_code = 'Q'; break;
296 #else
297 # error SIZEOF__BOOL has an unexpected value
298 #endif /* SIZEOF__BOOL */
299     default:
300         /* The standard-size code is the same as the ctypes one */
301         pep_code = code;
302         break;
303     }
304 
305     result = PyMem_Malloc(3);
306     if (result == NULL) {
307         PyErr_NoMemory();
308         return NULL;
309     }
310 
311     result[0] = big_endian ? '>' : '<';
312     result[1] = pep_code;
313     result[2] = '\0';
314     return result;
315 }
316 
317 /*
318   Allocate a memory block for a pep3118 format string, copy prefix (if
319   non-null) and suffix into it.  Returns NULL on failure, with the error
320   indicator set.  If called with a suffix of NULL the error indicator must
321   already be set.
322  */
323 char *
_ctypes_alloc_format_string(const char * prefix,const char * suffix)324 _ctypes_alloc_format_string(const char *prefix, const char *suffix)
325 {
326     size_t len;
327     char *result;
328 
329     if (suffix == NULL) {
330         assert(PyErr_Occurred());
331         return NULL;
332     }
333     len = strlen(suffix);
334     if (prefix)
335         len += strlen(prefix);
336     result = PyMem_Malloc(len + 1);
337     if (result == NULL) {
338         PyErr_NoMemory();
339         return NULL;
340     }
341     if (prefix)
342         strcpy(result, prefix);
343     else
344         result[0] = '\0';
345     strcat(result, suffix);
346     return result;
347 }
348 
349 /*
350   Allocate a memory block for a pep3118 format string, adding
351   the given prefix (if non-null), an additional shape prefix, and a suffix.
352   Returns NULL on failure, with the error indicator set.  If called with
353   a suffix of NULL the error indicator must already be set.
354  */
355 char *
_ctypes_alloc_format_string_with_shape(int ndim,const Py_ssize_t * shape,const char * prefix,const char * suffix)356 _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape,
357                                        const char *prefix, const char *suffix)
358 {
359     char *new_prefix;
360     char *result;
361     char buf[32];
362     Py_ssize_t prefix_len;
363     int k;
364 
365     prefix_len = 32 * ndim + 3;
366     if (prefix)
367         prefix_len += strlen(prefix);
368     new_prefix = PyMem_Malloc(prefix_len);
369     if (new_prefix == NULL) {
370         PyErr_NoMemory();
371         return NULL;
372     }
373     new_prefix[0] = '\0';
374     if (prefix)
375         strcpy(new_prefix, prefix);
376     if (ndim > 0) {
377         /* Add the prefix "(shape[0],shape[1],...,shape[ndim-1])" */
378         strcat(new_prefix, "(");
379         for (k = 0; k < ndim; ++k) {
380             if (k < ndim-1) {
381                 sprintf(buf, "%zd,", shape[k]);
382             } else {
383                 sprintf(buf, "%zd)", shape[k]);
384             }
385             strcat(new_prefix, buf);
386         }
387     }
388     result = _ctypes_alloc_format_string(new_prefix, suffix);
389     PyMem_Free(new_prefix);
390     return result;
391 }
392 
393 /* StructParamObject and StructParam_Type are used in _ctypes_callproc()
394    for argument.keep to call PyMem_Free(ptr) on Py_DECREF(argument).
395 
396    StructUnionType_paramfunc() creates such object when a ctypes Structure is
397    passed by copy to a C function. */
398 typedef struct {
399     PyObject_HEAD
400     void *ptr;
401     PyObject *keep;  // If set, a reference to the original CDataObject.
402 } StructParamObject;
403 
404 static int
StructParam_traverse(StructParamObject * self,visitproc visit,void * arg)405 StructParam_traverse(StructParamObject *self, visitproc visit, void *arg)
406 {
407     Py_VISIT(Py_TYPE(self));
408     return 0;
409 }
410 
411 static int
StructParam_clear(StructParamObject * self)412 StructParam_clear(StructParamObject *self)
413 {
414     Py_CLEAR(self->keep);
415     return 0;
416 }
417 
418 static void
StructParam_dealloc(PyObject * myself)419 StructParam_dealloc(PyObject *myself)
420 {
421     StructParamObject *self = (StructParamObject *)myself;
422     PyTypeObject *tp = Py_TYPE(self);
423     PyObject_GC_UnTrack(myself);
424     (void)StructParam_clear(self);
425     PyMem_Free(self->ptr);
426     tp->tp_free(myself);
427     Py_DECREF(tp);
428 }
429 
430 static PyType_Slot structparam_slots[] = {
431     {Py_tp_traverse, StructParam_traverse},
432     {Py_tp_clear, StructParam_clear},
433     {Py_tp_dealloc, StructParam_dealloc},
434     {0, NULL},
435 };
436 
437 static PyType_Spec structparam_spec = {
438     .name = "_ctypes.StructParam_Type",
439     .basicsize = sizeof(StructParamObject),
440     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
441               Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DISALLOW_INSTANTIATION),
442     .slots = structparam_slots,
443 };
444 
445 /*
446   CType_Type - a base metaclass. Its instances (classes) have a StgInfo.
447   */
448 
449 /*[clinic input]
450 class _ctypes.CType_Type "PyObject *" "clinic_state()->CType_Type"
451 [clinic start generated code]*/
452 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8389fc5b74a84f2a]*/
453 
454 static int
CType_Type_traverse(PyObject * self,visitproc visit,void * arg)455 CType_Type_traverse(PyObject *self, visitproc visit, void *arg)
456 {
457     StgInfo *info = _PyStgInfo_FromType_NoState(self);
458     if (!info) {
459         PyErr_WriteUnraisable(self);
460     }
461     if (info) {
462         Py_VISIT(info->proto);
463         Py_VISIT(info->argtypes);
464         Py_VISIT(info->converters);
465         Py_VISIT(info->restype);
466         Py_VISIT(info->checker);
467         Py_VISIT(info->module);
468     }
469     Py_VISIT(Py_TYPE(self));
470     return PyType_Type.tp_traverse(self, visit, arg);
471 }
472 
473 void
ctype_clear_stginfo(StgInfo * info)474 ctype_clear_stginfo(StgInfo *info)
475 {
476     assert(info);
477     Py_CLEAR(info->proto);
478     Py_CLEAR(info->argtypes);
479     Py_CLEAR(info->converters);
480     Py_CLEAR(info->restype);
481     Py_CLEAR(info->checker);
482     Py_CLEAR(info->module);
483 }
484 
485 static int
CType_Type_clear(PyObject * self)486 CType_Type_clear(PyObject *self)
487 {
488     StgInfo *info = _PyStgInfo_FromType_NoState(self);
489     if (!info) {
490         PyErr_WriteUnraisable(self);
491     }
492     if (info) {
493         ctype_clear_stginfo(info);
494     }
495     return PyType_Type.tp_clear(self);
496 }
497 
498 static void
CType_Type_dealloc(PyObject * self)499 CType_Type_dealloc(PyObject *self)
500 {
501     StgInfo *info = _PyStgInfo_FromType_NoState(self);
502     if (!info) {
503         PyErr_WriteUnraisable(self);
504     }
505     if (info) {
506         PyMem_Free(info->ffi_type_pointer.elements);
507         info->ffi_type_pointer.elements = NULL;
508         PyMem_Free(info->format);
509         info->format = NULL;
510         PyMem_Free(info->shape);
511         info->shape = NULL;
512         ctype_clear_stginfo(info);
513     }
514 
515     PyTypeObject *tp = Py_TYPE(self);
516     PyType_Type.tp_dealloc(self);
517     Py_DECREF(tp);
518 }
519 
520 /*[clinic input]
521 _ctypes.CType_Type.__sizeof__
522 
523     cls: defining_class
524     /
525 Return memory consumption of the type object.
526 [clinic start generated code]*/
527 
528 static PyObject *
_ctypes_CType_Type___sizeof___impl(PyObject * self,PyTypeObject * cls)529 _ctypes_CType_Type___sizeof___impl(PyObject *self, PyTypeObject *cls)
530 /*[clinic end generated code: output=c68c235be84d03f3 input=d064433b6110d1ce]*/
531 {
532     Py_ssize_t size = Py_TYPE(self)->tp_basicsize;
533     size += Py_TYPE(self)->tp_itemsize * Py_SIZE(self);
534 
535     ctypes_state *st = get_module_state_by_class(cls);
536     StgInfo *info;
537     if (PyStgInfo_FromType(st, self, &info) < 0) {
538         return NULL;
539     }
540     if (info) {
541         if (info->format) {
542             size += strlen(info->format) + 1;
543         }
544         if (info->ffi_type_pointer.elements) {
545             size += (info->length + 1) * sizeof(ffi_type *);
546         }
547         size += info->ndim * sizeof(Py_ssize_t);
548     }
549 
550     return PyLong_FromSsize_t(size);
551 }
552 
553 static PyObject *
554 CType_Type_repeat(PyObject *self, Py_ssize_t length);
555 
556 
557 static PyMethodDef ctype_methods[] = {
558     _CTYPES_CTYPE_TYPE___SIZEOF___METHODDEF
559     {0},
560 };
561 
562 static PyType_Slot ctype_type_slots[] = {
563     {Py_tp_traverse, CType_Type_traverse},
564     {Py_tp_clear, CType_Type_clear},
565     {Py_tp_dealloc, CType_Type_dealloc},
566     {Py_tp_methods, ctype_methods},
567     // Sequence protocol.
568     {Py_sq_repeat, CType_Type_repeat},
569     {0, NULL},
570 };
571 
572 static PyType_Spec pyctype_type_spec = {
573     .name = "_ctypes.CType_Type",
574     .basicsize = -(Py_ssize_t)sizeof(StgInfo),
575     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE |
576               Py_TPFLAGS_HAVE_GC |
577               Py_TPFLAGS_BASETYPE ),
578     .slots = ctype_type_slots,
579 };
580 
581 /*
582   PyCStructType_Type - a meta type/class.  Creating a new class using this one as
583   __metaclass__ will call the constructor StructUnionType_new.
584   It initializes the C accessible fields somehow.
585 */
586 
587 static PyCArgObject *
StructUnionType_paramfunc(ctypes_state * st,CDataObject * self)588 StructUnionType_paramfunc(ctypes_state *st, CDataObject *self)
589 {
590     PyCArgObject *parg;
591     PyObject *obj;
592     void *ptr;
593 
594     if ((size_t)self->b_size > sizeof(void*)) {
595         ptr = PyMem_Malloc(self->b_size);
596         if (ptr == NULL) {
597             return NULL;
598         }
599         memcpy(ptr, self->b_ptr, self->b_size);
600 
601         /* Create a Python object which calls PyMem_Free(ptr) in
602            its deallocator. The object will be destroyed
603            at _ctypes_callproc() cleanup. */
604         PyTypeObject *tp = st->StructParam_Type;
605         obj = tp->tp_alloc(tp, 0);
606         if (obj == NULL) {
607             PyMem_Free(ptr);
608             return NULL;
609         }
610 
611         StructParamObject *struct_param = (StructParamObject *)obj;
612         struct_param->ptr = ptr;
613         struct_param->keep = Py_NewRef(self);
614     } else {
615         ptr = self->b_ptr;
616         obj = Py_NewRef(self);
617     }
618 
619     parg = PyCArgObject_new(st);
620     if (parg == NULL) {
621         Py_DECREF(obj);
622         return NULL;
623     }
624 
625     StgInfo *stginfo;
626     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
627         Py_DECREF(obj);
628         return NULL;
629     }
630     assert(stginfo); /* Cannot be NULL for structure/union instances */
631 
632     parg->tag = 'V';
633     parg->pffi_type = &stginfo->ffi_type_pointer;
634     parg->value.p = ptr;
635     parg->size = self->b_size;
636     parg->obj = obj;
637     return parg;
638 }
639 
640 static int
StructUnionType_init(PyObject * self,PyObject * args,PyObject * kwds,int isStruct)641 StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruct)
642 {
643     PyObject *fields;
644 
645     PyObject *attrdict = PyType_GetDict((PyTypeObject *)self);
646     if (!attrdict) {
647         return -1;
648     }
649 
650     /* keep this for bw compatibility */
651     int r = PyDict_Contains(attrdict, &_Py_ID(_abstract_));
652     if (r > 0) {
653         Py_DECREF(attrdict);
654         return 0;
655     }
656     if (r < 0) {
657         Py_DECREF(attrdict);
658         return -1;
659     }
660 
661     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
662     StgInfo *info = PyStgInfo_Init(st, (PyTypeObject *)self);
663     if (!info) {
664         Py_DECREF(attrdict);
665         return -1;
666     }
667     if (!isStruct) {
668         info->flags |= TYPEFLAG_HASUNION;
669     }
670 
671     info->format = _ctypes_alloc_format_string(NULL, "B");
672     if (info->format == NULL) {
673         Py_DECREF(attrdict);
674         return -1;
675     }
676 
677     info->paramfunc = StructUnionType_paramfunc;
678 
679     if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_fields_), &fields) < 0) {
680         Py_DECREF(attrdict);
681         return -1;
682     }
683     Py_CLEAR(attrdict);
684     if (fields) {
685         if (PyObject_SetAttr(self, &_Py_ID(_fields_), fields) < 0) {
686             Py_DECREF(fields);
687             return -1;
688         }
689         Py_DECREF(fields);
690         return 0;
691     }
692     else {
693         StgInfo *baseinfo;
694         if (PyStgInfo_FromType(st, (PyObject *)((PyTypeObject *)self)->tp_base,
695                                &baseinfo) < 0) {
696             return -1;
697         }
698         if (baseinfo == NULL) {
699             return 0;
700         }
701 
702         /* copy base info */
703         if (PyCStgInfo_clone(info, baseinfo) < 0) {
704             return -1;
705         }
706         info->flags &= ~DICTFLAG_FINAL; /* clear the 'final' flag in the subclass info */
707         baseinfo->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass info */
708     }
709     return 0;
710 }
711 
712 static int
PyCStructType_init(PyObject * self,PyObject * args,PyObject * kwds)713 PyCStructType_init(PyObject *self, PyObject *args, PyObject *kwds)
714 {
715     return StructUnionType_init(self, args, kwds, 1);
716 }
717 
718 static int
UnionType_init(PyObject * self,PyObject * args,PyObject * kwds)719 UnionType_init(PyObject *self, PyObject *args, PyObject *kwds)
720 {
721     return StructUnionType_init(self, args, kwds, 0);
722 }
723 
724 /*[clinic input]
725 class _ctypes.CDataType "PyObject *" "clinic_state()->CType_Type"
726 [clinic start generated code]*/
727 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=466a505a93d73156]*/
728 
729 
730 /*[clinic input]
731 _ctypes.CDataType.from_address as CDataType_from_address
732 
733     type: self
734     cls: defining_class
735     value: object
736     /
737 
738 C.from_address(integer) -> C instance
739 
740 Access a C instance at the specified address.
741 [clinic start generated code]*/
742 
743 static PyObject *
CDataType_from_address_impl(PyObject * type,PyTypeObject * cls,PyObject * value)744 CDataType_from_address_impl(PyObject *type, PyTypeObject *cls,
745                             PyObject *value)
746 /*[clinic end generated code: output=5be4a7c0d9aa6c74 input=827a22cefe380c01]*/
747 {
748     void *buf;
749     if (!PyLong_Check(value)) {
750         PyErr_SetString(PyExc_TypeError,
751                         "integer expected");
752         return NULL;
753     }
754     buf = (void *)PyLong_AsVoidPtr(value);
755     if (PyErr_Occurred())
756         return NULL;
757     ctypes_state *st = get_module_state_by_class(cls);
758     return PyCData_AtAddress(st, type, buf);
759 }
760 
761 static int
762 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep);
763 
764 /*[clinic input]
765 _ctypes.CDataType.from_buffer as CDataType_from_buffer
766 
767     type: self
768     cls: defining_class
769     obj: object
770     offset: Py_ssize_t = 0
771     /
772 
773 C.from_buffer(object, offset=0) -> C instance
774 
775 Create a C instance from a writeable buffer.
776 [clinic start generated code]*/
777 
778 static PyObject *
CDataType_from_buffer_impl(PyObject * type,PyTypeObject * cls,PyObject * obj,Py_ssize_t offset)779 CDataType_from_buffer_impl(PyObject *type, PyTypeObject *cls, PyObject *obj,
780                            Py_ssize_t offset)
781 /*[clinic end generated code: output=57604e99635abd31 input=0f36cedd105ca28d]*/
782 {
783     PyObject *mv;
784     PyObject *result;
785     Py_buffer *buffer;
786 
787     ctypes_state *st = get_module_state_by_class(cls);
788     StgInfo *info;
789     if (PyStgInfo_FromType(st, type, &info) < 0) {
790         return NULL;
791     }
792     if (!info) {
793         PyErr_SetString(PyExc_TypeError, "abstract class");
794         return NULL;
795     }
796 
797     mv = PyMemoryView_FromObject(obj);
798     if (mv == NULL)
799         return NULL;
800 
801     buffer = PyMemoryView_GET_BUFFER(mv);
802 
803     if (buffer->readonly) {
804         PyErr_SetString(PyExc_TypeError,
805             "underlying buffer is not writable");
806         Py_DECREF(mv);
807         return NULL;
808     }
809 
810     if (!PyBuffer_IsContiguous(buffer, 'C')) {
811         PyErr_SetString(PyExc_TypeError,
812             "underlying buffer is not C contiguous");
813         Py_DECREF(mv);
814         return NULL;
815     }
816 
817     if (offset < 0) {
818         PyErr_SetString(PyExc_ValueError,
819                         "offset cannot be negative");
820         Py_DECREF(mv);
821         return NULL;
822     }
823 
824     if (info->size > buffer->len - offset) {
825         PyErr_Format(PyExc_ValueError,
826                      "Buffer size too small "
827                      "(%zd instead of at least %zd bytes)",
828                      buffer->len, info->size + offset);
829         Py_DECREF(mv);
830         return NULL;
831     }
832 
833     if (PySys_Audit("ctypes.cdata/buffer", "nnn",
834                     (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) {
835         Py_DECREF(mv);
836         return NULL;
837     }
838 
839     result = PyCData_AtAddress(st, type, (char *)buffer->buf + offset);
840     if (result == NULL) {
841         Py_DECREF(mv);
842         return NULL;
843     }
844 
845     if (-1 == KeepRef((CDataObject *)result, -1, mv)) {
846         Py_DECREF(result);
847         return NULL;
848     }
849 
850     return result;
851 }
852 
853 static inline PyObject *
854 generic_pycdata_new(ctypes_state *st,
855                     PyTypeObject *type, PyObject *args, PyObject *kwds);
856 
857 static PyObject *
858 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
859 
860 /*[clinic input]
861 _ctypes.CDataType.from_buffer_copy as CDataType_from_buffer_copy
862 
863     type: self
864     cls: defining_class
865     buffer: Py_buffer
866     offset: Py_ssize_t = 0
867     /
868 
869 C.from_buffer_copy(object, offset=0) -> C instance
870 
871 Create a C instance from a readable buffer.
872 [clinic start generated code]*/
873 
874 static PyObject *
CDataType_from_buffer_copy_impl(PyObject * type,PyTypeObject * cls,Py_buffer * buffer,Py_ssize_t offset)875 CDataType_from_buffer_copy_impl(PyObject *type, PyTypeObject *cls,
876                                 Py_buffer *buffer, Py_ssize_t offset)
877 /*[clinic end generated code: output=c8fc62b03e5cc6fa input=2a81e11b765a6253]*/
878 {
879     PyObject *result;
880 
881     ctypes_state *st = get_module_state_by_class(cls);
882     StgInfo *info;
883     if (PyStgInfo_FromType(st, type, &info) < 0) {
884         return NULL;
885     }
886     if (!info) {
887         PyErr_SetString(PyExc_TypeError, "abstract class");
888         return NULL;
889     }
890 
891     if (offset < 0) {
892         PyErr_SetString(PyExc_ValueError,
893                         "offset cannot be negative");
894         return NULL;
895     }
896 
897     if (info->size > buffer->len - offset) {
898         PyErr_Format(PyExc_ValueError,
899                      "Buffer size too small (%zd instead of at least %zd bytes)",
900                      buffer->len, info->size + offset);
901         return NULL;
902     }
903 
904     if (PySys_Audit("ctypes.cdata/buffer", "nnn",
905                     (Py_ssize_t)buffer->buf, buffer->len, offset) < 0) {
906         return NULL;
907     }
908 
909     result = generic_pycdata_new(st, (PyTypeObject *)type, NULL, NULL);
910     if (result != NULL) {
911         memcpy(((CDataObject *)result)->b_ptr,
912                (char *)buffer->buf + offset, info->size);
913     }
914     return result;
915 }
916 
917 /*[clinic input]
918 _ctypes.CDataType.in_dll as CDataType_in_dll
919 
920     type: self
921     cls: defining_class
922     dll: object
923     name: str
924     /
925 
926 C.in_dll(dll, name) -> C instance
927 
928 Access a C instance in a dll.
929 [clinic start generated code]*/
930 
931 static PyObject *
CDataType_in_dll_impl(PyObject * type,PyTypeObject * cls,PyObject * dll,const char * name)932 CDataType_in_dll_impl(PyObject *type, PyTypeObject *cls, PyObject *dll,
933                       const char *name)
934 /*[clinic end generated code: output=d0e5c43b66bfa21f input=f85bf281477042b4]*/
935 {
936     PyObject *obj;
937     void *handle;
938     void *address;
939 
940     if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) {
941         return NULL;
942     }
943 
944     obj = PyObject_GetAttrString(dll, "_handle");
945     if (!obj)
946         return NULL;
947     if (!PyLong_Check(obj)) {
948         PyErr_SetString(PyExc_TypeError,
949                         "the _handle attribute of the second argument must be an integer");
950         Py_DECREF(obj);
951         return NULL;
952     }
953     handle = (void *)PyLong_AsVoidPtr(obj);
954     Py_DECREF(obj);
955     if (PyErr_Occurred()) {
956         PyErr_SetString(PyExc_ValueError,
957                         "could not convert the _handle attribute to a pointer");
958         return NULL;
959     }
960 
961 #undef USE_DLERROR
962 #ifdef MS_WIN32
963     Py_BEGIN_ALLOW_THREADS
964     address = (void *)GetProcAddress(handle, name);
965     Py_END_ALLOW_THREADS
966 #else
967     #ifdef __CYGWIN__
968         // dlerror() isn't very helpful on cygwin
969     #else
970         #define USE_DLERROR
971         /* dlerror() always returns the latest error.
972          *
973          * Clear the previous value before calling dlsym(),
974          * to ensure we can tell if our call resulted in an error.
975          */
976         (void)dlerror();
977     #endif
978     address = (void *)dlsym(handle, name);
979 #endif
980 
981     if (address) {
982         ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
983         return PyCData_AtAddress(st, type, address);
984     }
985 
986     #ifdef USE_DLERROR
987     const char *dlerr = dlerror();
988     if (dlerr) {
989         PyObject *message = PyUnicode_DecodeLocale(dlerr, "surrogateescape");
990         if (message) {
991             PyErr_SetObject(PyExc_ValueError, message);
992             Py_DECREF(message);
993             return NULL;
994         }
995         // Ignore errors from PyUnicode_DecodeLocale,
996         // fall back to the generic error below.
997         PyErr_Clear();
998     }
999     #endif
1000 #undef USE_DLERROR
1001     PyErr_Format(PyExc_ValueError, "symbol '%s' not found", name);
1002     return NULL;
1003 }
1004 
1005 /*[clinic input]
1006 _ctypes.CDataType.from_param as CDataType_from_param
1007 
1008     type: self
1009     cls: defining_class
1010     value: object
1011     /
1012 
1013 Convert a Python object into a function call parameter.
1014 [clinic start generated code]*/
1015 
1016 static PyObject *
CDataType_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)1017 CDataType_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
1018 /*[clinic end generated code: output=8da9e34263309f9e input=275a52c4899ddff0]*/
1019 {
1020     PyObject *as_parameter;
1021     int res = PyObject_IsInstance(value, type);
1022     if (res == -1)
1023         return NULL;
1024     if (res) {
1025         return Py_NewRef(value);
1026     }
1027     ctypes_state *st = get_module_state_by_class(cls);
1028     if (PyCArg_CheckExact(st, value)) {
1029         PyCArgObject *p = (PyCArgObject *)value;
1030         PyObject *ob = p->obj;
1031         const char *ob_name;
1032         StgInfo *info;
1033         if (PyStgInfo_FromType(st, type, &info) < 0) {
1034             return NULL;
1035         }
1036         /* If we got a PyCArgObject, we must check if the object packed in it
1037            is an instance of the type's info->proto */
1038         if(info && ob) {
1039             res = PyObject_IsInstance(ob, info->proto);
1040             if (res == -1)
1041                 return NULL;
1042             if (res) {
1043                 return Py_NewRef(value);
1044             }
1045         }
1046         ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???";
1047         PyErr_Format(PyExc_TypeError,
1048                      "expected %s instance instead of pointer to %s",
1049                      ((PyTypeObject *)type)->tp_name, ob_name);
1050         return NULL;
1051     }
1052 
1053     if (PyObject_GetOptionalAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) {
1054         return NULL;
1055     }
1056     if (as_parameter) {
1057         value = CDataType_from_param_impl(type, cls, as_parameter);
1058         Py_DECREF(as_parameter);
1059         return value;
1060     }
1061     PyErr_Format(PyExc_TypeError,
1062                  "expected %s instance instead of %s",
1063                  ((PyTypeObject *)type)->tp_name,
1064                  Py_TYPE(value)->tp_name);
1065     return NULL;
1066 }
1067 
1068 static PyMethodDef CDataType_methods[] = {
1069     CDATATYPE_FROM_PARAM_METHODDEF
1070     CDATATYPE_FROM_ADDRESS_METHODDEF
1071     CDATATYPE_FROM_BUFFER_METHODDEF
1072     CDATATYPE_FROM_BUFFER_COPY_METHODDEF
1073     CDATATYPE_IN_DLL_METHODDEF
1074     { NULL, NULL },
1075 };
1076 
1077 static PyObject *
CType_Type_repeat(PyObject * self,Py_ssize_t length)1078 CType_Type_repeat(PyObject *self, Py_ssize_t length)
1079 {
1080     if (length < 0)
1081         return PyErr_Format(PyExc_ValueError,
1082                             "Array length must be >= 0, not %zd",
1083                             length);
1084     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
1085     return PyCArrayType_from_ctype(st, self, length);
1086 }
1087 
1088 
1089 static int
PyCStructType_setattro(PyObject * self,PyObject * key,PyObject * value)1090 PyCStructType_setattro(PyObject *self, PyObject *key, PyObject *value)
1091 {
1092     /* XXX Should we disallow deleting _fields_? */
1093     if (-1 == PyType_Type.tp_setattro(self, key, value))
1094         return -1;
1095 
1096     if (value && PyUnicode_Check(key) &&
1097         _PyUnicode_EqualToASCIIString(key, "_fields_"))
1098         return PyCStructUnionType_update_stginfo(self, value, 1);
1099     return 0;
1100 }
1101 
1102 
1103 static int
UnionType_setattro(PyObject * self,PyObject * key,PyObject * value)1104 UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
1105 {
1106     /* XXX Should we disallow deleting _fields_? */
1107     if (-1 == PyType_Type.tp_setattro(self, key, value))
1108         return -1;
1109 
1110     if (PyUnicode_Check(key) &&
1111         _PyUnicode_EqualToASCIIString(key, "_fields_"))
1112         return PyCStructUnionType_update_stginfo(self, value, 0);
1113     return 0;
1114 }
1115 
1116 static PyType_Slot pycstruct_type_slots[] = {
1117     {Py_tp_setattro, PyCStructType_setattro},
1118     {Py_tp_doc, PyDoc_STR("metatype for the CData Objects")},
1119     {Py_tp_methods, CDataType_methods},
1120     {Py_tp_init, PyCStructType_init},
1121     {0, NULL},
1122 };
1123 
1124 static PyType_Spec pycstruct_type_spec = {
1125     .name = "_ctypes.PyCStructType",
1126     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1127               Py_TPFLAGS_IMMUTABLETYPE),
1128     .slots = pycstruct_type_slots,
1129 };
1130 
1131 static PyType_Slot union_type_slots[] = {
1132     {Py_tp_setattro, UnionType_setattro},
1133     {Py_tp_doc, PyDoc_STR("metatype for the Union Objects")},
1134     {Py_tp_methods, CDataType_methods},
1135     {Py_tp_init, UnionType_init},
1136     {0, NULL},
1137 };
1138 
1139 static PyType_Spec union_type_spec = {
1140     .name = "_ctypes.UnionType",
1141     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1142               Py_TPFLAGS_IMMUTABLETYPE),
1143     .slots = union_type_slots,
1144 };
1145 
1146 /******************************************************************/
1147 
1148 /*
1149 
1150 The PyCPointerType_Type metaclass must ensure that the subclass of Pointer can be
1151 created. It must check for a _type_ attribute in the class. Since are no
1152 runtime created properties, a CField is probably *not* needed ?
1153 
1154 class IntPointer(Pointer):
1155     _type_ = "i"
1156 
1157 The PyCPointer_Type provides the functionality: a contents method/property, a
1158 size property/method, and the sequence protocol.
1159 
1160 */
1161 
1162 /*[clinic input]
1163 class _ctypes.PyCPointerType "PyObject *" "clinic_state()->PyCPointerType_Type"
1164 [clinic start generated code]*/
1165 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c45e96c1f7645ab7]*/
1166 
1167 
1168 static int
PyCPointerType_SetProto(ctypes_state * st,StgInfo * stginfo,PyObject * proto)1169 PyCPointerType_SetProto(ctypes_state *st, StgInfo *stginfo, PyObject *proto)
1170 {
1171     if (!proto || !PyType_Check(proto)) {
1172         PyErr_SetString(PyExc_TypeError,
1173                         "_type_ must be a type");
1174         return -1;
1175     }
1176     StgInfo *info;
1177     if (PyStgInfo_FromType(st, proto, &info) < 0) {
1178         return -1;
1179     }
1180     if (!info) {
1181         PyErr_SetString(PyExc_TypeError,
1182                         "_type_ must have storage info");
1183         return -1;
1184     }
1185     Py_INCREF(proto);
1186     Py_XSETREF(stginfo->proto, proto);
1187     return 0;
1188 }
1189 
1190 static PyCArgObject *
PyCPointerType_paramfunc(ctypes_state * st,CDataObject * self)1191 PyCPointerType_paramfunc(ctypes_state *st, CDataObject *self)
1192 {
1193     PyCArgObject *parg;
1194 
1195     parg = PyCArgObject_new(st);
1196     if (parg == NULL)
1197         return NULL;
1198 
1199     parg->tag = 'P';
1200     parg->pffi_type = &ffi_type_pointer;
1201     parg->obj = Py_NewRef(self);
1202     parg->value.p = *(void **)self->b_ptr;
1203     return parg;
1204 }
1205 
1206 static int
PyCPointerType_init(PyObject * self,PyObject * args,PyObject * kwds)1207 PyCPointerType_init(PyObject *self, PyObject *args, PyObject *kwds)
1208 {
1209     PyObject *proto;
1210     PyObject *typedict;
1211 
1212     typedict = PyTuple_GetItem(args, 2);
1213     if (!typedict) {
1214         return -1;
1215     }
1216 
1217 /*
1218   stginfo items size, align, length contain info about pointers itself,
1219   stginfo->proto has info about the pointed to type!
1220 */
1221     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
1222     StgInfo *stginfo = PyStgInfo_Init(st, (PyTypeObject *)self);
1223     if (!stginfo) {
1224         return -1;
1225     }
1226     stginfo->size = sizeof(void *);
1227     stginfo->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
1228     stginfo->length = 1;
1229     stginfo->ffi_type_pointer = ffi_type_pointer;
1230     stginfo->paramfunc = PyCPointerType_paramfunc;
1231     stginfo->flags |= TYPEFLAG_ISPOINTER;
1232 
1233     if (PyDict_GetItemRef(typedict, &_Py_ID(_type_), &proto) < 0) {
1234         return -1;
1235     }
1236     if (proto) {
1237         const char *current_format;
1238         if (PyCPointerType_SetProto(st, stginfo, proto) < 0) {
1239             Py_DECREF(proto);
1240             return -1;
1241         }
1242         StgInfo *iteminfo;
1243         if (PyStgInfo_FromType(st, proto, &iteminfo) < 0) {
1244             Py_DECREF(proto);
1245             return -1;
1246         }
1247         /* PyCPointerType_SetProto has verified proto has a stginfo. */
1248         assert(iteminfo);
1249         /* If iteminfo->format is NULL, then this is a pointer to an
1250            incomplete type.  We create a generic format string
1251            'pointer to bytes' in this case.  XXX Better would be to
1252            fix the format string later...
1253         */
1254         current_format = iteminfo->format ? iteminfo->format : "B";
1255         if (iteminfo->shape != NULL) {
1256             /* pointer to an array: the shape needs to be prefixed */
1257             stginfo->format = _ctypes_alloc_format_string_with_shape(
1258                 iteminfo->ndim, iteminfo->shape, "&", current_format);
1259         } else {
1260             stginfo->format = _ctypes_alloc_format_string("&", current_format);
1261         }
1262         Py_DECREF(proto);
1263         if (stginfo->format == NULL) {
1264             return -1;
1265         }
1266     }
1267 
1268     return 0;
1269 }
1270 
1271 /*[clinic input]
1272 _ctypes.PyCPointerType.set_type as PyCPointerType_set_type
1273 
1274     self: self(type="PyTypeObject *")
1275     cls: defining_class
1276     type: object
1277     /
1278 [clinic start generated code]*/
1279 
1280 static PyObject *
PyCPointerType_set_type_impl(PyTypeObject * self,PyTypeObject * cls,PyObject * type)1281 PyCPointerType_set_type_impl(PyTypeObject *self, PyTypeObject *cls,
1282                              PyObject *type)
1283 /*[clinic end generated code: output=51459d8f429a70ac input=67e1e8df921f123e]*/
1284 {
1285     PyObject *attrdict = PyType_GetDict(self);
1286     if (!attrdict) {
1287         return NULL;
1288     }
1289     ctypes_state *st = get_module_state_by_class(cls);
1290     StgInfo *info;
1291     if (PyStgInfo_FromType(st, (PyObject *)self, &info) < 0) {
1292         Py_DECREF(attrdict);
1293         return NULL;
1294     }
1295     if (!info) {
1296         PyErr_SetString(PyExc_TypeError,
1297                         "abstract class");
1298         Py_DECREF(attrdict);
1299         return NULL;
1300     }
1301 
1302     if (PyCPointerType_SetProto(st, info, type) < 0) {
1303         Py_DECREF(attrdict);
1304         return NULL;
1305     }
1306 
1307     if (-1 == PyDict_SetItem(attrdict, &_Py_ID(_type_), type)) {
1308         Py_DECREF(attrdict);
1309         return NULL;
1310     }
1311 
1312     Py_DECREF(attrdict);
1313     Py_RETURN_NONE;
1314 }
1315 
1316 static PyObject *_byref(ctypes_state *, PyObject *);
1317 
1318 /*[clinic input]
1319 _ctypes.PyCPointerType.from_param as PyCPointerType_from_param
1320 
1321     type: self
1322     cls: defining_class
1323     value: object
1324     /
1325 
1326 Convert a Python object into a function call parameter.
1327 [clinic start generated code]*/
1328 
1329 static PyObject *
PyCPointerType_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)1330 PyCPointerType_from_param_impl(PyObject *type, PyTypeObject *cls,
1331                                PyObject *value)
1332 /*[clinic end generated code: output=a4b32d929aabaf64 input=6c231276e3997884]*/
1333 {
1334     if (value == Py_None) {
1335         /* ConvParam will convert to a NULL pointer later */
1336         return Py_NewRef(value);
1337     }
1338 
1339     ctypes_state *st = get_module_state_by_class(cls);
1340     StgInfo *typeinfo;
1341     if (PyStgInfo_FromType(st, type, &typeinfo) < 0) {
1342         return NULL;
1343     }
1344     if (!typeinfo) {
1345         PyErr_SetString(PyExc_TypeError,
1346                         "abstract class");
1347         return NULL;
1348     }
1349 
1350     /* If we expect POINTER(<type>), but receive a <type> instance, accept
1351        it by calling byref(<type>).
1352     */
1353     assert(typeinfo->proto);
1354     switch (PyObject_IsInstance(value, typeinfo->proto)) {
1355     case 1:
1356         Py_INCREF(value); /* _byref steals a refcount */
1357         return _byref(st, value);
1358     case -1:
1359         return NULL;
1360     default:
1361         break;
1362     }
1363 
1364     if (PointerObject_Check(st, value) || ArrayObject_Check(st, value)) {
1365         /* Array instances are also pointers when
1366            the item types are the same.
1367         */
1368         StgInfo *v;
1369         if (PyStgInfo_FromObject(st, value, &v) < 0) {
1370             return NULL;
1371         }
1372         assert(v); /* Cannot be NULL for pointer or array objects */
1373         int ret = PyObject_IsSubclass(v->proto, typeinfo->proto);
1374         if (ret < 0) {
1375             return NULL;
1376         }
1377         if (ret) {
1378             return Py_NewRef(value);
1379         }
1380     }
1381     return CDataType_from_param_impl(type, cls, value);
1382 }
1383 
1384 static PyMethodDef PyCPointerType_methods[] = {
1385     CDATATYPE_FROM_ADDRESS_METHODDEF
1386     CDATATYPE_FROM_BUFFER_METHODDEF
1387     CDATATYPE_FROM_BUFFER_COPY_METHODDEF
1388     CDATATYPE_IN_DLL_METHODDEF
1389     PYCPOINTERTYPE_FROM_PARAM_METHODDEF
1390     PYCPOINTERTYPE_SET_TYPE_METHODDEF
1391     { NULL, NULL },
1392 };
1393 
1394 static PyType_Slot pycpointer_type_slots[] = {
1395     {Py_tp_doc, PyDoc_STR("metatype for the Pointer Objects")},
1396     {Py_tp_methods, PyCPointerType_methods},
1397     {Py_tp_init, PyCPointerType_init},
1398     {0, NULL},
1399 };
1400 
1401 static PyType_Spec pycpointer_type_spec = {
1402     .name = "_ctypes.PyCPointerType",
1403     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1404               Py_TPFLAGS_IMMUTABLETYPE),
1405     .slots = pycpointer_type_slots,
1406 };
1407 
1408 
1409 /******************************************************************/
1410 /*
1411   PyCArrayType_Type
1412 */
1413 /*
1414   PyCArrayType_init ensures that the new Array subclass created has a _length_
1415   attribute, and a _type_ attribute.
1416 */
1417 
1418 static int
CharArray_set_raw(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1419 CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1420 {
1421     char *ptr;
1422     Py_ssize_t size;
1423     Py_buffer view;
1424 
1425     if (value == NULL) {
1426         PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
1427         return -1;
1428     }
1429     if (PyObject_GetBuffer(value, &view, PyBUF_SIMPLE) < 0)
1430         return -1;
1431     size = view.len;
1432     ptr = view.buf;
1433     if (size > self->b_size) {
1434         PyErr_SetString(PyExc_ValueError,
1435                         "byte string too long");
1436         goto fail;
1437     }
1438 
1439     memcpy(self->b_ptr, ptr, size);
1440 
1441     PyBuffer_Release(&view);
1442     return 0;
1443  fail:
1444     PyBuffer_Release(&view);
1445     return -1;
1446 }
1447 
1448 static PyObject *
CharArray_get_raw(CDataObject * self,void * Py_UNUSED (ignored))1449 CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
1450 {
1451     return PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
1452 }
1453 
1454 static PyObject *
CharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1455 CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1456 {
1457     Py_ssize_t i;
1458     char *ptr = self->b_ptr;
1459     for (i = 0; i < self->b_size; ++i)
1460         if (*ptr++ == '\0')
1461             break;
1462     return PyBytes_FromStringAndSize(self->b_ptr, i);
1463 }
1464 
1465 static int
CharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1466 CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1467 {
1468     const char *ptr;
1469     Py_ssize_t size;
1470 
1471     if (value == NULL) {
1472         PyErr_SetString(PyExc_TypeError,
1473                         "can't delete attribute");
1474         return -1;
1475     }
1476 
1477     if (!PyBytes_Check(value)) {
1478         PyErr_Format(PyExc_TypeError,
1479                      "bytes expected instead of %s instance",
1480                      Py_TYPE(value)->tp_name);
1481         return -1;
1482     } else
1483         Py_INCREF(value);
1484     size = PyBytes_GET_SIZE(value);
1485     if (size > self->b_size) {
1486         PyErr_SetString(PyExc_ValueError,
1487                         "byte string too long");
1488         Py_DECREF(value);
1489         return -1;
1490     }
1491 
1492     ptr = PyBytes_AS_STRING(value);
1493     memcpy(self->b_ptr, ptr, size);
1494     if (size < self->b_size)
1495         self->b_ptr[size] = '\0';
1496     Py_DECREF(value);
1497 
1498     return 0;
1499 }
1500 
1501 static PyGetSetDef CharArray_getsets[] = {
1502     { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
1503       "value", NULL },
1504     { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
1505       "string value"},
1506     { NULL, NULL }
1507 };
1508 
1509 static PyObject *
WCharArray_get_value(CDataObject * self,void * Py_UNUSED (ignored))1510 WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
1511 {
1512     Py_ssize_t i;
1513     wchar_t *ptr = (wchar_t *)self->b_ptr;
1514     for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
1515         if (*ptr++ == (wchar_t)0)
1516             break;
1517     return PyUnicode_FromWideChar((wchar_t *)self->b_ptr, i);
1518 }
1519 
1520 static int
WCharArray_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))1521 WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
1522 {
1523     if (value == NULL) {
1524         PyErr_SetString(PyExc_TypeError,
1525                         "can't delete attribute");
1526         return -1;
1527     }
1528     if (!PyUnicode_Check(value)) {
1529         PyErr_Format(PyExc_TypeError,
1530                         "unicode string expected instead of %s instance",
1531                         Py_TYPE(value)->tp_name);
1532         return -1;
1533     }
1534 
1535     Py_ssize_t size = self->b_size / sizeof(wchar_t);
1536     Py_ssize_t len = PyUnicode_AsWideChar(value, NULL, 0);
1537     if (len < 0) {
1538         return -1;
1539     }
1540     // PyUnicode_AsWideChar() returns number of wchars including trailing null byte,
1541     // when it is called with NULL.
1542     assert(len > 0);
1543     if (len - 1 > size) {
1544         PyErr_SetString(PyExc_ValueError, "string too long");
1545         return -1;
1546     }
1547     if (PyUnicode_AsWideChar(value, (wchar_t *)self->b_ptr, size) < 0) {
1548         return -1;
1549     }
1550     return 0;
1551 }
1552 
1553 static PyGetSetDef WCharArray_getsets[] = {
1554     { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
1555       "string value"},
1556     { NULL, NULL }
1557 };
1558 
1559 /*
1560   The next function is copied from Python's typeobject.c.
1561 
1562   It is used to attach getsets to a type *after* it
1563   has been created: Arrays of characters have additional getsets to treat them
1564   as strings.
1565  */
1566 
1567 static int
add_getset(PyTypeObject * type,PyGetSetDef * gsp)1568 add_getset(PyTypeObject *type, PyGetSetDef *gsp)
1569 {
1570     PyObject *dict = type->tp_dict;
1571     for (; gsp->name != NULL; gsp++) {
1572         PyObject *descr;
1573         descr = PyDescr_NewGetSet(type, gsp);
1574         if (descr == NULL)
1575             return -1;
1576         if (PyDict_SetItemString(dict, gsp->name, descr) < 0) {
1577             Py_DECREF(descr);
1578             return -1;
1579         }
1580         Py_DECREF(descr);
1581     }
1582     return 0;
1583 }
1584 
1585 static PyCArgObject *
PyCArrayType_paramfunc(ctypes_state * st,CDataObject * self)1586 PyCArrayType_paramfunc(ctypes_state *st, CDataObject *self)
1587 {
1588     PyCArgObject *p = PyCArgObject_new(st);
1589     if (p == NULL)
1590         return NULL;
1591     p->tag = 'P';
1592     p->pffi_type = &ffi_type_pointer;
1593     p->value.p = (char *)self->b_ptr;
1594     p->obj = Py_NewRef(self);
1595     return p;
1596 }
1597 
1598 static int
PyCArrayType_init(PyObject * self,PyObject * args,PyObject * kwds)1599 PyCArrayType_init(PyObject *self, PyObject *args, PyObject *kwds)
1600 {
1601     PyObject *length_attr, *type_attr;
1602     Py_ssize_t length;
1603     Py_ssize_t itemsize, itemalign;
1604 
1605     /* Initialize these variables to NULL so that we can simplify error
1606        handling by using Py_XDECREF.  */
1607     type_attr = NULL;
1608 
1609     if (PyObject_GetOptionalAttr(self, &_Py_ID(_length_), &length_attr) < 0) {
1610         goto error;
1611     }
1612     if (!length_attr) {
1613         PyErr_SetString(PyExc_AttributeError,
1614                         "class must define a '_length_' attribute");
1615         goto error;
1616     }
1617 
1618     if (!PyLong_Check(length_attr)) {
1619         Py_DECREF(length_attr);
1620         PyErr_SetString(PyExc_TypeError,
1621                         "The '_length_' attribute must be an integer");
1622         goto error;
1623     }
1624 
1625     if (_PyLong_Sign(length_attr) == -1) {
1626         Py_DECREF(length_attr);
1627         PyErr_SetString(PyExc_ValueError,
1628                         "The '_length_' attribute must not be negative");
1629         goto error;
1630     }
1631 
1632     length = PyLong_AsSsize_t(length_attr);
1633     Py_DECREF(length_attr);
1634     if (length == -1 && PyErr_Occurred()) {
1635         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
1636             PyErr_SetString(PyExc_OverflowError,
1637                             "The '_length_' attribute is too large");
1638         }
1639         goto error;
1640     }
1641 
1642     if (PyObject_GetOptionalAttr(self, &_Py_ID(_type_), &type_attr) < 0) {
1643         goto error;
1644     }
1645     if (!type_attr) {
1646         PyErr_SetString(PyExc_AttributeError,
1647                         "class must define a '_type_' attribute");
1648         goto error;
1649     }
1650 
1651     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
1652     StgInfo *stginfo = PyStgInfo_Init(st, (PyTypeObject*)self);
1653     if (!stginfo) {
1654         goto error;
1655     }
1656 
1657     StgInfo *iteminfo;
1658     if (PyStgInfo_FromType(st, type_attr, &iteminfo) < 0) {
1659         goto error;
1660     }
1661     if (!iteminfo) {
1662         PyErr_SetString(PyExc_TypeError,
1663                         "_type_ must have storage info");
1664         goto error;
1665     }
1666 
1667     assert(iteminfo->format);
1668     stginfo->format = _ctypes_alloc_format_string(NULL, iteminfo->format);
1669     if (stginfo->format == NULL)
1670         goto error;
1671     stginfo->ndim = iteminfo->ndim + 1;
1672     stginfo->shape = PyMem_Malloc(sizeof(Py_ssize_t) * stginfo->ndim);
1673     if (stginfo->shape == NULL) {
1674         PyErr_NoMemory();
1675         goto error;
1676     }
1677     stginfo->shape[0] = length;
1678     if (stginfo->ndim > 1) {
1679         memmove(&stginfo->shape[1], iteminfo->shape,
1680             sizeof(Py_ssize_t) * (stginfo->ndim - 1));
1681     }
1682 
1683     itemsize = iteminfo->size;
1684     if (itemsize != 0 && length > PY_SSIZE_T_MAX / itemsize) {
1685         PyErr_SetString(PyExc_OverflowError,
1686                         "array too large");
1687         goto error;
1688     }
1689 
1690     itemalign = iteminfo->align;
1691 
1692     if (iteminfo->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
1693         stginfo->flags |= TYPEFLAG_HASPOINTER;
1694 
1695     stginfo->size = itemsize * length;
1696     stginfo->align = itemalign;
1697     stginfo->length = length;
1698     stginfo->proto = type_attr;
1699     type_attr = NULL;
1700 
1701     stginfo->paramfunc = &PyCArrayType_paramfunc;
1702 
1703     /* Arrays are passed as pointers to function calls. */
1704     stginfo->ffi_type_pointer = ffi_type_pointer;
1705 
1706     /* Special case for character arrays.
1707        A permanent annoyance: char arrays are also strings!
1708     */
1709     if (iteminfo->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
1710         if (-1 == add_getset((PyTypeObject*)self, CharArray_getsets))
1711             goto error;
1712     }
1713     else if (iteminfo->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
1714         if (-1 == add_getset((PyTypeObject*)self, WCharArray_getsets))
1715             goto error;
1716     }
1717 
1718     return 0;
1719 error:
1720     Py_XDECREF(type_attr);
1721     return -1;
1722 }
1723 
1724 static PyType_Slot pycarray_type_slots[] = {
1725     {Py_tp_doc, PyDoc_STR("metatype for the Array Objects")},
1726     {Py_tp_methods, CDataType_methods},
1727     {Py_tp_init, PyCArrayType_init},
1728     {0, NULL},
1729 };
1730 
1731 static PyType_Spec pycarray_type_spec = {
1732     .name = "_ctypes.PyCArrayType",
1733     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
1734               Py_TPFLAGS_IMMUTABLETYPE),
1735     .slots = pycarray_type_slots,
1736 };
1737 
1738 /******************************************************************/
1739 /*
1740   PyCSimpleType_Type
1741 */
1742 /*
1743 
1744 PyCSimpleType_init ensures that the new Simple_Type subclass created has a valid
1745 _type_ attribute.
1746 
1747 */
1748 
1749 /*[clinic input]
1750 class _ctypes.PyCSimpleType "PyObject *" "clinic_state()->PyCSimpleType_Type"
1751 [clinic start generated code]*/
1752 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=d5a45772668e7f49]*/
1753 
1754 /*[clinic input]
1755 class _ctypes.c_wchar_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
1756 [clinic start generated code]*/
1757 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=468de7283d622d47]*/
1758 
1759 /*[clinic input]
1760 class _ctypes.c_char_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
1761 [clinic start generated code]*/
1762 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e750865616e7dcea]*/
1763 
1764 /*[clinic input]
1765 class _ctypes.c_void_p "PyObject *" "clinic_state_sub()->PyCSimpleType_Type"
1766 [clinic start generated code]*/
1767 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd4d9646c56f43a9]*/
1768 
1769 static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
1770 
1771 /*[clinic input]
1772 _ctypes.c_wchar_p.from_param as c_wchar_p_from_param
1773 
1774     type: self
1775     cls: defining_class
1776     value: object
1777     /
1778 [clinic start generated code]*/
1779 
1780 static PyObject *
c_wchar_p_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)1781 c_wchar_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
1782 /*[clinic end generated code: output=e453949a2f725a4c input=d322c7237a319607]*/
1783 {
1784     PyObject *as_parameter;
1785     int res;
1786     if (value == Py_None) {
1787         Py_RETURN_NONE;
1788     }
1789     ctypes_state *st = get_module_state_by_class(cls->tp_base);
1790     if (PyUnicode_Check(value)) {
1791         PyCArgObject *parg;
1792         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
1793 
1794         parg = PyCArgObject_new(st);
1795         if (parg == NULL)
1796             return NULL;
1797         parg->pffi_type = &ffi_type_pointer;
1798         parg->tag = 'Z';
1799         parg->obj = fd->setfunc(&parg->value, value, 0);
1800         if (parg->obj == NULL) {
1801             Py_DECREF(parg);
1802             return NULL;
1803         }
1804         return (PyObject *)parg;
1805     }
1806     res = PyObject_IsInstance(value, type);
1807     if (res == -1)
1808         return NULL;
1809     if (res) {
1810         return Py_NewRef(value);
1811     }
1812     if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
1813         /* c_wchar array instance or pointer(c_wchar(...)) */
1814         StgInfo *it;
1815         if (PyStgInfo_FromObject(st, value, &it) < 0) {
1816             return NULL;
1817         }
1818         assert(it); /* Cannot be NULL for pointer or array objects */
1819         StgInfo *info = NULL;
1820         if (it && it->proto) {
1821             if (PyStgInfo_FromType(st, it->proto, &info) < 0) {
1822                 return NULL;
1823             }
1824         }
1825         if (info && (info->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1826             return Py_NewRef(value);
1827         }
1828     }
1829     if (PyCArg_CheckExact(st, value)) {
1830         /* byref(c_char(...)) */
1831         PyCArgObject *a = (PyCArgObject *)value;
1832         StgInfo *info;
1833         if (PyStgInfo_FromObject(st, a->obj, &info) < 0) {
1834             return NULL;
1835         }
1836         if (info && (info->setfunc == _ctypes_get_fielddesc("u")->setfunc)) {
1837             return Py_NewRef(value);
1838         }
1839     }
1840 
1841     if (PyObject_GetOptionalAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) {
1842         return NULL;
1843     }
1844     if (as_parameter) {
1845         value = c_wchar_p_from_param_impl(type, cls, as_parameter);
1846         Py_DECREF(as_parameter);
1847         return value;
1848     }
1849     PyErr_Format(PyExc_TypeError,
1850                  "'%.200s' object cannot be interpreted "
1851                  "as ctypes.c_wchar_p", Py_TYPE(value)->tp_name);
1852     return NULL;
1853 }
1854 
1855 /*[clinic input]
1856 _ctypes.c_char_p.from_param as c_char_p_from_param
1857 
1858     type: self
1859     cls: defining_class
1860     value: object
1861     /
1862 [clinic start generated code]*/
1863 
1864 static PyObject *
c_char_p_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)1865 c_char_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
1866 /*[clinic end generated code: output=219652ab7c174aa1 input=6cf0d1b6bb4ede11]*/
1867 {
1868     PyObject *as_parameter;
1869     int res;
1870     if (value == Py_None) {
1871         Py_RETURN_NONE;
1872     }
1873     ctypes_state *st = get_module_state_by_class(cls->tp_base);
1874     if (PyBytes_Check(value)) {
1875         PyCArgObject *parg;
1876         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1877 
1878         parg = PyCArgObject_new(st);
1879         if (parg == NULL)
1880             return NULL;
1881         parg->pffi_type = &ffi_type_pointer;
1882         parg->tag = 'z';
1883         parg->obj = fd->setfunc(&parg->value, value, 0);
1884         if (parg->obj == NULL) {
1885             Py_DECREF(parg);
1886             return NULL;
1887         }
1888         return (PyObject *)parg;
1889     }
1890     res = PyObject_IsInstance(value, type);
1891     if (res == -1)
1892         return NULL;
1893     if (res) {
1894         return Py_NewRef(value);
1895     }
1896     if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
1897         /* c_char array instance or pointer(c_char(...)) */
1898         StgInfo *it;
1899         if (PyStgInfo_FromObject(st, value, &it) < 0) {
1900             return NULL;
1901         }
1902         assert(it); /* Cannot be NULL for pointer or array objects */
1903         StgInfo *info = NULL;
1904         if (it && it->proto) {
1905             if (PyStgInfo_FromType(st, it->proto, &info) < 0) {
1906                 return NULL;
1907             }
1908         }
1909         if (info && (info->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1910             return Py_NewRef(value);
1911         }
1912     }
1913     if (PyCArg_CheckExact(st, value)) {
1914         /* byref(c_char(...)) */
1915         PyCArgObject *a = (PyCArgObject *)value;
1916         StgInfo *info;
1917         if (PyStgInfo_FromObject(st, a->obj, &info) < 0) {
1918             return NULL;
1919         }
1920         if (info && (info->setfunc == _ctypes_get_fielddesc("c")->setfunc)) {
1921             return Py_NewRef(value);
1922         }
1923     }
1924 
1925     if (PyObject_GetOptionalAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) {
1926         return NULL;
1927     }
1928     if (as_parameter) {
1929         value = c_char_p_from_param_impl(type, cls, as_parameter);
1930         Py_DECREF(as_parameter);
1931         return value;
1932     }
1933     PyErr_Format(PyExc_TypeError,
1934                  "'%.200s' object cannot be interpreted "
1935                  "as ctypes.c_char_p", Py_TYPE(value)->tp_name);
1936     return NULL;
1937 }
1938 
1939 /*[clinic input]
1940 _ctypes.c_void_p.from_param as c_void_p_from_param
1941 
1942     type: self
1943     cls: defining_class
1944     value: object
1945     /
1946 [clinic start generated code]*/
1947 
1948 static PyObject *
c_void_p_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)1949 c_void_p_from_param_impl(PyObject *type, PyTypeObject *cls, PyObject *value)
1950 /*[clinic end generated code: output=984d0075b6038cc7 input=0e8b343fc19c77d4]*/
1951 {
1952     PyObject *as_parameter;
1953     int res;
1954 
1955 /* None */
1956     if (value == Py_None) {
1957         Py_RETURN_NONE;
1958     }
1959     ctypes_state *st = get_module_state_by_class(cls->tp_base);
1960 
1961     /* Should probably allow buffer interface as well */
1962 /* int, long */
1963     if (PyLong_Check(value)) {
1964         PyCArgObject *parg;
1965         struct fielddesc *fd = _ctypes_get_fielddesc("P");
1966 
1967         parg = PyCArgObject_new(st);
1968         if (parg == NULL)
1969             return NULL;
1970         parg->pffi_type = &ffi_type_pointer;
1971         parg->tag = 'P';
1972         parg->obj = fd->setfunc(&parg->value, value, 0);
1973         if (parg->obj == NULL) {
1974             Py_DECREF(parg);
1975             return NULL;
1976         }
1977         return (PyObject *)parg;
1978     }
1979     /* XXX struni: remove later */
1980 /* bytes */
1981     if (PyBytes_Check(value)) {
1982         PyCArgObject *parg;
1983         struct fielddesc *fd = _ctypes_get_fielddesc("z");
1984 
1985         parg = PyCArgObject_new(st);
1986         if (parg == NULL)
1987             return NULL;
1988         parg->pffi_type = &ffi_type_pointer;
1989         parg->tag = 'z';
1990         parg->obj = fd->setfunc(&parg->value, value, 0);
1991         if (parg->obj == NULL) {
1992             Py_DECREF(parg);
1993             return NULL;
1994         }
1995         return (PyObject *)parg;
1996     }
1997 /* unicode */
1998     if (PyUnicode_Check(value)) {
1999         PyCArgObject *parg;
2000         struct fielddesc *fd = _ctypes_get_fielddesc("Z");
2001 
2002         parg = PyCArgObject_new(st);
2003         if (parg == NULL)
2004             return NULL;
2005         parg->pffi_type = &ffi_type_pointer;
2006         parg->tag = 'Z';
2007         parg->obj = fd->setfunc(&parg->value, value, 0);
2008         if (parg->obj == NULL) {
2009             Py_DECREF(parg);
2010             return NULL;
2011         }
2012         return (PyObject *)parg;
2013     }
2014 /* c_void_p instance (or subclass) */
2015     res = PyObject_IsInstance(value, type);
2016     if (res == -1)
2017         return NULL;
2018     if (res) {
2019         /* c_void_p instances */
2020         return Py_NewRef(value);
2021     }
2022 /* ctypes array or pointer instance */
2023     if (ArrayObject_Check(st, value) || PointerObject_Check(st, value)) {
2024         /* Any array or pointer is accepted */
2025         return Py_NewRef(value);
2026     }
2027 /* byref(...) */
2028     if (PyCArg_CheckExact(st, value)) {
2029         /* byref(c_xxx()) */
2030         PyCArgObject *a = (PyCArgObject *)value;
2031         if (a->tag == 'P') {
2032             return Py_NewRef(value);
2033         }
2034     }
2035 /* function pointer */
2036     if (PyCFuncPtrObject_Check(st, value)) {
2037         PyCArgObject *parg;
2038         PyCFuncPtrObject *func;
2039         func = (PyCFuncPtrObject *)value;
2040         parg = PyCArgObject_new(st);
2041         if (parg == NULL)
2042             return NULL;
2043         parg->pffi_type = &ffi_type_pointer;
2044         parg->tag = 'P';
2045         Py_INCREF(value);
2046         parg->value.p = *(void **)func->b_ptr;
2047         parg->obj = value;
2048         return (PyObject *)parg;
2049     }
2050 /* c_char_p, c_wchar_p */
2051     StgInfo *stgi;
2052     if (PyStgInfo_FromObject(st, value, &stgi) < 0) {
2053         return NULL;
2054     }
2055     if (stgi
2056         && CDataObject_Check(st, value)
2057         && stgi->proto
2058         && PyUnicode_Check(stgi->proto))
2059     {
2060         PyCArgObject *parg;
2061 
2062         switch (PyUnicode_AsUTF8(stgi->proto)[0]) {
2063         case 'z': /* c_char_p */
2064         case 'Z': /* c_wchar_p */
2065             parg = PyCArgObject_new(st);
2066             if (parg == NULL)
2067                 return NULL;
2068             parg->pffi_type = &ffi_type_pointer;
2069             parg->tag = 'Z';
2070             parg->obj = Py_NewRef(value);
2071             /* Remember: b_ptr points to where the pointer is stored! */
2072             parg->value.p = *(void **)(((CDataObject *)value)->b_ptr);
2073             return (PyObject *)parg;
2074         }
2075     }
2076 
2077     if (PyObject_GetOptionalAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) {
2078         return NULL;
2079     }
2080     if (as_parameter) {
2081         value = c_void_p_from_param_impl(type, cls, as_parameter);
2082         Py_DECREF(as_parameter);
2083         return value;
2084     }
2085     PyErr_Format(PyExc_TypeError,
2086                  "'%.200s' object cannot be interpreted "
2087                  "as ctypes.c_void_p", Py_TYPE(value)->tp_name);
2088     return NULL;
2089 }
2090 
2091 static PyMethodDef c_void_p_methods[] = {C_VOID_P_FROM_PARAM_METHODDEF {0}};
2092 static PyMethodDef c_char_p_methods[] = {C_CHAR_P_FROM_PARAM_METHODDEF {0}};
2093 static PyMethodDef c_wchar_p_methods[] = {C_WCHAR_P_FROM_PARAM_METHODDEF {0}};
2094 
CreateSwappedType(ctypes_state * st,PyTypeObject * type,PyObject * args,PyObject * kwds,PyObject * proto,struct fielddesc * fmt)2095 static PyObject *CreateSwappedType(ctypes_state *st, PyTypeObject *type,
2096                                    PyObject *args, PyObject *kwds,
2097                                    PyObject *proto, struct fielddesc *fmt)
2098 {
2099     PyTypeObject *result;
2100     PyObject *name = PyTuple_GET_ITEM(args, 0);
2101     PyObject *newname;
2102     PyObject *swapped_args;
2103     Py_ssize_t i;
2104 
2105     swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
2106     if (!swapped_args)
2107         return NULL;
2108 
2109     if (st->swapped_suffix == NULL) {
2110 #ifdef WORDS_BIGENDIAN
2111         st->swapped_suffix = PyUnicode_InternFromString("_le");
2112 #else
2113         st->swapped_suffix = PyUnicode_InternFromString("_be");
2114 #endif
2115     }
2116     if (st->swapped_suffix == NULL) {
2117         Py_DECREF(swapped_args);
2118         return NULL;
2119     }
2120 
2121     newname = PyUnicode_Concat(name, st->swapped_suffix);
2122     if (newname == NULL) {
2123         Py_DECREF(swapped_args);
2124         return NULL;
2125     }
2126 
2127     PyTuple_SET_ITEM(swapped_args, 0, newname);
2128     for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
2129         PyObject *v = PyTuple_GET_ITEM(args, i);
2130         Py_INCREF(v);
2131         PyTuple_SET_ITEM(swapped_args, i, v);
2132     }
2133 
2134     /* create the new instance (which is a class,
2135        since we are a metatype!) */
2136     result = (PyTypeObject *)PyType_Type.tp_new(type, swapped_args, kwds);
2137     Py_DECREF(swapped_args);
2138     if (result == NULL)
2139         return NULL;
2140 
2141     StgInfo *stginfo = PyStgInfo_Init(st, result);
2142     if (!stginfo) {
2143         Py_DECREF(result);
2144         return NULL;
2145     }
2146 
2147     stginfo->ffi_type_pointer = *fmt->pffi_type;
2148     stginfo->align = fmt->pffi_type->alignment;
2149     stginfo->length = 0;
2150     stginfo->size = fmt->pffi_type->size;
2151     stginfo->setfunc = fmt->setfunc_swapped;
2152     stginfo->getfunc = fmt->getfunc_swapped;
2153 
2154     stginfo->proto = Py_NewRef(proto);
2155 
2156     return (PyObject *)result;
2157 }
2158 
2159 static PyCArgObject *
PyCSimpleType_paramfunc(ctypes_state * st,CDataObject * self)2160 PyCSimpleType_paramfunc(ctypes_state *st, CDataObject *self)
2161 {
2162     const char *fmt;
2163     PyCArgObject *parg;
2164     struct fielddesc *fd;
2165 
2166     StgInfo *info;
2167     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
2168         return NULL;
2169     }
2170     assert(info); /* Cannot be NULL for CDataObject instances */
2171     fmt = PyUnicode_AsUTF8(info->proto);
2172     assert(fmt);
2173 
2174     fd = _ctypes_get_fielddesc(fmt);
2175     assert(fd);
2176 
2177     parg = PyCArgObject_new(st);
2178     if (parg == NULL)
2179         return NULL;
2180 
2181     parg->tag = fmt[0];
2182     parg->pffi_type = fd->pffi_type;
2183     parg->obj = Py_NewRef(self);
2184     memcpy(&parg->value, self->b_ptr, self->b_size);
2185     return parg;
2186 }
2187 
2188 static int
PyCSimpleType_init(PyObject * self,PyObject * args,PyObject * kwds)2189 PyCSimpleType_init(PyObject *self, PyObject *args, PyObject *kwds)
2190 {
2191     PyObject *proto;
2192     const char *proto_str;
2193     Py_ssize_t proto_len;
2194     PyMethodDef *ml;
2195     struct fielddesc *fmt;
2196 
2197     if (PyType_Type.tp_init(self, args, kwds) < 0) {
2198         return -1;
2199     }
2200     if (PyObject_GetOptionalAttr(self, &_Py_ID(_type_), &proto) < 0) {
2201         return -1;
2202     }
2203     if (!proto) {
2204         PyErr_SetString(PyExc_AttributeError,
2205                         "class must define a '_type_' attribute");
2206   error:
2207         Py_XDECREF(proto);
2208         return -1;
2209     }
2210     if (PyUnicode_Check(proto)) {
2211         proto_str = PyUnicode_AsUTF8AndSize(proto, &proto_len);
2212         if (!proto_str)
2213             goto error;
2214     } else {
2215         PyErr_SetString(PyExc_TypeError,
2216             "class must define a '_type_' string attribute");
2217         goto error;
2218     }
2219     if (proto_len != 1) {
2220         PyErr_SetString(PyExc_ValueError,
2221                         "class must define a '_type_' attribute "
2222                         "which must be a string of length 1");
2223         goto error;
2224     }
2225     if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
2226         PyErr_Format(PyExc_AttributeError,
2227                      "class must define a '_type_' attribute which must be\n"
2228                      "a single character string containing one of '%s'.",
2229                      SIMPLE_TYPE_CHARS);
2230         goto error;
2231     }
2232     fmt = _ctypes_get_fielddesc(proto_str);
2233     if (fmt == NULL) {
2234         PyErr_Format(PyExc_ValueError,
2235                      "_type_ '%s' not supported", proto_str);
2236         goto error;
2237     }
2238 
2239     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
2240     StgInfo *stginfo = PyStgInfo_Init(st, (PyTypeObject *)self);
2241     if (!stginfo) {
2242         goto error;
2243     }
2244 
2245     stginfo->ffi_type_pointer = *fmt->pffi_type;
2246     stginfo->align = fmt->pffi_type->alignment;
2247     stginfo->length = 0;
2248     stginfo->size = fmt->pffi_type->size;
2249     stginfo->setfunc = fmt->setfunc;
2250     stginfo->getfunc = fmt->getfunc;
2251 #ifdef WORDS_BIGENDIAN
2252     stginfo->format = _ctypes_alloc_format_string_for_type(proto_str[0], 1);
2253 #else
2254     stginfo->format = _ctypes_alloc_format_string_for_type(proto_str[0], 0);
2255 #endif
2256     if (stginfo->format == NULL) {
2257         Py_DECREF(proto);
2258         return -1;
2259     }
2260 
2261     stginfo->paramfunc = PyCSimpleType_paramfunc;
2262 /*
2263     if (self->tp_base != st->Simple_Type) {
2264         stginfo->setfunc = NULL;
2265         stginfo->getfunc = NULL;
2266     }
2267 */
2268 
2269     /* This consumes the refcount on proto which we have */
2270     stginfo->proto = proto;
2271 
2272     /* Install from_param class methods in ctypes base classes.
2273        Overrides the PyCSimpleType_from_param generic method.
2274      */
2275     if (((PyTypeObject *)self)->tp_base == st->Simple_Type) {
2276         switch (*proto_str) {
2277         case 'z': /* c_char_p */
2278             ml = c_char_p_methods;
2279             stginfo->flags |= TYPEFLAG_ISPOINTER;
2280             break;
2281         case 'Z': /* c_wchar_p */
2282             ml = c_wchar_p_methods;
2283             stginfo->flags |= TYPEFLAG_ISPOINTER;
2284             break;
2285         case 'P': /* c_void_p */
2286             ml = c_void_p_methods;
2287             stginfo->flags |= TYPEFLAG_ISPOINTER;
2288             break;
2289         case 's':
2290         case 'X':
2291         case 'O':
2292             ml = NULL;
2293             stginfo->flags |= TYPEFLAG_ISPOINTER;
2294             break;
2295         default:
2296             ml = NULL;
2297             break;
2298         }
2299 
2300         if (ml) {
2301             PyObject *meth;
2302             int x;
2303             meth = PyDescr_NewClassMethod((PyTypeObject*)self, ml);
2304             if (!meth) {
2305                 return -1;
2306             }
2307             PyObject *name = PyUnicode_FromString(ml->ml_name);
2308             if (name == NULL) {
2309                 Py_DECREF(meth);
2310                 return -1;
2311             }
2312             PyUnicode_InternInPlace(&name);
2313             x = PyDict_SetItem(((PyTypeObject*)self)->tp_dict, name, meth);
2314             Py_DECREF(name);
2315             Py_DECREF(meth);
2316             if (x == -1) {
2317                 return -1;
2318             }
2319         }
2320     }
2321 
2322     PyTypeObject *type = Py_TYPE(self);
2323     if (type == st->PyCSimpleType_Type
2324         && fmt->setfunc_swapped
2325         && fmt->getfunc_swapped)
2326     {
2327         PyObject *swapped = CreateSwappedType(st, type, args, kwds,
2328                                               proto, fmt);
2329         if (swapped == NULL) {
2330             return -1;
2331         }
2332         StgInfo *sw_info;
2333         if (PyStgInfo_FromType(st, swapped, &sw_info) < 0) {
2334             return -1;
2335         }
2336         assert(sw_info);
2337 #ifdef WORDS_BIGENDIAN
2338         PyObject_SetAttrString(self, "__ctype_le__", swapped);
2339         PyObject_SetAttrString(self, "__ctype_be__", self);
2340         PyObject_SetAttrString(swapped, "__ctype_be__", self);
2341         PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
2342         /* We are creating the type for the OTHER endian */
2343         sw_info->format = _ctypes_alloc_format_string("<", stginfo->format+1);
2344 #else
2345         PyObject_SetAttrString(self, "__ctype_be__", swapped);
2346         PyObject_SetAttrString(self, "__ctype_le__", self);
2347         PyObject_SetAttrString(swapped, "__ctype_le__", self);
2348         PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
2349         /* We are creating the type for the OTHER endian */
2350         sw_info->format = _ctypes_alloc_format_string(">", stginfo->format+1);
2351 #endif
2352         Py_DECREF(swapped);
2353         if (PyErr_Occurred()) {
2354             return -1;
2355         }
2356     };
2357 
2358     return 0;
2359 }
2360 
2361 /*
2362  * This is a *class method*.
2363  * Convert a parameter into something that ConvParam can handle.
2364  */
2365 
2366 /*[clinic input]
2367 _ctypes.PyCSimpleType.from_param as PyCSimpleType_from_param
2368 
2369     type: self
2370     cls: defining_class
2371     value: object
2372     /
2373 
2374 Convert a Python object into a function call parameter.
2375 [clinic start generated code]*/
2376 
2377 static PyObject *
PyCSimpleType_from_param_impl(PyObject * type,PyTypeObject * cls,PyObject * value)2378 PyCSimpleType_from_param_impl(PyObject *type, PyTypeObject *cls,
2379                               PyObject *value)
2380 /*[clinic end generated code: output=8a8453d9663e3a2e input=61cc48ce3a87a570]*/
2381 {
2382     const char *fmt;
2383     PyCArgObject *parg;
2384     struct fielddesc *fd;
2385     PyObject *as_parameter;
2386     int res;
2387 
2388     /* If the value is already an instance of the requested type,
2389        we can use it as is */
2390     res = PyObject_IsInstance(value, type);
2391     if (res == -1)
2392         return NULL;
2393     if (res) {
2394         return Py_NewRef(value);
2395     }
2396 
2397     ctypes_state *st = get_module_state_by_class(cls);
2398     StgInfo *info;
2399     if (PyStgInfo_FromType(st, type, &info) < 0) {
2400         return NULL;
2401     }
2402     if (!info) {
2403         PyErr_SetString(PyExc_TypeError,
2404                         "abstract class");
2405         return NULL;
2406     }
2407 
2408     /* I think we can rely on this being a one-character string */
2409     fmt = PyUnicode_AsUTF8(info->proto);
2410     assert(fmt);
2411 
2412     fd = _ctypes_get_fielddesc(fmt);
2413     assert(fd);
2414 
2415     parg = PyCArgObject_new(st);
2416     if (parg == NULL)
2417         return NULL;
2418 
2419     parg->tag = fmt[0];
2420     parg->pffi_type = fd->pffi_type;
2421     parg->obj = fd->setfunc(&parg->value, value, 0);
2422     if (parg->obj)
2423         return (PyObject *)parg;
2424     PyObject *exc = PyErr_GetRaisedException();
2425     Py_DECREF(parg);
2426 
2427     if (PyObject_GetOptionalAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) {
2428         Py_XDECREF(exc);
2429         return NULL;
2430     }
2431     if (as_parameter) {
2432         if (_Py_EnterRecursiveCall(" while processing _as_parameter_")) {
2433             Py_DECREF(as_parameter);
2434             Py_XDECREF(exc);
2435             return NULL;
2436         }
2437         value = PyCSimpleType_from_param_impl(type, cls, as_parameter);
2438         _Py_LeaveRecursiveCall();
2439         Py_DECREF(as_parameter);
2440         Py_XDECREF(exc);
2441         return value;
2442     }
2443     if (exc) {
2444         PyErr_SetRaisedException(exc);
2445     }
2446     else {
2447         PyErr_SetString(PyExc_TypeError, "wrong type");
2448     }
2449     return NULL;
2450 }
2451 
2452 static PyMethodDef PyCSimpleType_methods[] = {
2453     PYCSIMPLETYPE_FROM_PARAM_METHODDEF
2454     CDATATYPE_FROM_ADDRESS_METHODDEF
2455     CDATATYPE_FROM_BUFFER_METHODDEF
2456     CDATATYPE_FROM_BUFFER_COPY_METHODDEF
2457     CDATATYPE_IN_DLL_METHODDEF
2458     { NULL, NULL },
2459 };
2460 
2461 static PyType_Slot pycsimple_type_slots[] = {
2462     {Py_tp_doc, PyDoc_STR("metatype for the PyCSimpleType Objects")},
2463     {Py_tp_methods, PyCSimpleType_methods},
2464     {Py_tp_init, PyCSimpleType_init},
2465     {0, NULL},
2466 };
2467 
2468 static PyType_Spec pycsimple_type_spec = {
2469     .name = "_ctypes.PyCSimpleType",
2470     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2471               Py_TPFLAGS_IMMUTABLETYPE),
2472     .slots = pycsimple_type_slots,
2473 };
2474 
2475 /******************************************************************/
2476 /*
2477   PyCFuncPtrType_Type
2478  */
2479 
2480 static PyObject *
converters_from_argtypes(ctypes_state * st,PyObject * ob)2481 converters_from_argtypes(ctypes_state *st, PyObject *ob)
2482 {
2483     PyObject *converters;
2484     Py_ssize_t i;
2485 
2486     ob = PySequence_Tuple(ob); /* new reference */
2487     if (!ob) {
2488         PyErr_SetString(PyExc_TypeError,
2489                         "_argtypes_ must be a sequence of types");
2490         return NULL;
2491     }
2492 
2493     Py_ssize_t nArgs = PyTuple_GET_SIZE(ob);
2494     if (nArgs > CTYPES_MAX_ARGCOUNT) {
2495         Py_DECREF(ob);
2496         PyErr_Format(st->PyExc_ArgError,
2497                      "_argtypes_ has too many arguments (%zi), maximum is %i",
2498                      nArgs, CTYPES_MAX_ARGCOUNT);
2499         return NULL;
2500     }
2501 
2502     converters = PyTuple_New(nArgs);
2503     if (!converters) {
2504         Py_DECREF(ob);
2505         return NULL;
2506     }
2507 
2508     /* I have to check if this is correct. Using c_char, which has a size
2509        of 1, will be assumed to be pushed as only one byte!
2510        Aren't these promoted to integers by the C compiler and pushed as 4 bytes?
2511     */
2512 
2513     for (i = 0; i < nArgs; ++i) {
2514         PyObject *cnv;
2515         PyObject *tp = PyTuple_GET_ITEM(ob, i);
2516 /*
2517  *      The following checks, relating to bpo-16575 and bpo-16576, have been
2518  *      disabled. The reason is that, although there is a definite problem with
2519  *      how libffi handles unions (https://github.com/libffi/libffi/issues/33),
2520  *      there are numerous libraries which pass structures containing unions
2521  *      by values - especially on Windows but examples also exist on Linux
2522  *      (https://bugs.python.org/msg359834).
2523  *
2524  *      It may not be possible to get proper support for unions and bitfields
2525  *      until support is forthcoming in libffi, but for now, adding the checks
2526  *      has caused problems in otherwise-working software, which suggests it
2527  *      is better to disable the checks.
2528  *
2529  *      Although specific examples reported relate specifically to unions and
2530  *      not bitfields, the bitfields check is also being disabled as a
2531  *      precaution.
2532 
2533         StgInfo *stginfo;
2534         if (PyStgInfo_FromType(st, tp, &stginfo) < 0) {
2535             return -1;
2536         }
2537 
2538         if (stginfo != NULL) {
2539             if (stginfo->flags & TYPEFLAG_HASUNION) {
2540                 Py_DECREF(converters);
2541                 Py_DECREF(ob);
2542                 if (!PyErr_Occurred()) {
2543                     PyErr_Format(PyExc_TypeError,
2544                                  "item %zd in _argtypes_ passes a union by "
2545                                  "value, which is unsupported.",
2546                                  i + 1);
2547                 }
2548                 return NULL;
2549             }
2550             if (stginfo->flags & TYPEFLAG_HASBITFIELD) {
2551                 Py_DECREF(converters);
2552                 Py_DECREF(ob);
2553                 if (!PyErr_Occurred()) {
2554                     PyErr_Format(PyExc_TypeError,
2555                                  "item %zd in _argtypes_ passes a struct/"
2556                                  "union with a bitfield by value, which is "
2557                                  "unsupported.",
2558                                  i + 1);
2559                 }
2560                 return NULL;
2561             }
2562         }
2563  */
2564 
2565         if (PyObject_GetOptionalAttr(tp, &_Py_ID(from_param), &cnv) <= 0) {
2566             Py_DECREF(converters);
2567             Py_DECREF(ob);
2568             if (!PyErr_Occurred()) {
2569                 PyErr_Format(PyExc_TypeError,
2570                              "item %zd in _argtypes_ has no from_param method",
2571                              i+1);
2572             }
2573             return NULL;
2574         }
2575         PyTuple_SET_ITEM(converters, i, cnv);
2576     }
2577     Py_DECREF(ob);
2578     return converters;
2579 }
2580 
2581 static int
make_funcptrtype_dict(ctypes_state * st,PyObject * attrdict,StgInfo * stginfo)2582 make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
2583 {
2584     PyObject *ob;
2585     PyObject *converters = NULL;
2586 
2587     stginfo->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
2588     stginfo->length = 1;
2589     stginfo->size = sizeof(void *);
2590     stginfo->setfunc = NULL;
2591     stginfo->getfunc = NULL;
2592     stginfo->ffi_type_pointer = ffi_type_pointer;
2593 
2594     if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_flags_), &ob) < 0) {
2595         return -1;
2596     }
2597     if (!ob || !PyLong_Check(ob)) {
2598         PyErr_SetString(PyExc_TypeError,
2599                 "class must define _flags_ which must be an integer");
2600         Py_XDECREF(ob);
2601         return -1;
2602     }
2603     stginfo->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
2604     Py_DECREF(ob);
2605 
2606     /* _argtypes_ is optional... */
2607     if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_argtypes_), &ob) < 0) {
2608         return -1;
2609     }
2610     if (ob) {
2611         converters = converters_from_argtypes(st, ob);
2612         if (!converters) {
2613             Py_DECREF(ob);
2614             return -1;
2615         }
2616         stginfo->argtypes = ob;
2617         stginfo->converters = converters;
2618     }
2619 
2620     if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_restype_), &ob) < 0) {
2621         return -1;
2622     }
2623     if (ob) {
2624         StgInfo *info;
2625         if (PyStgInfo_FromType(st, ob, &info) < 0) {
2626             return -1;
2627         }
2628         if (ob != Py_None && !info && !PyCallable_Check(ob)) {
2629             PyErr_SetString(PyExc_TypeError,
2630                 "_restype_ must be a type, a callable, or None");
2631             Py_DECREF(ob);
2632             return -1;
2633         }
2634         stginfo->restype = ob;
2635         if (PyObject_GetOptionalAttr(ob, &_Py_ID(_check_retval_),
2636                                    &stginfo->checker) < 0)
2637         {
2638             return -1;
2639         }
2640     }
2641 /* XXX later, maybe.
2642     if (PyDict_GetItemRef((PyObject *)attrdict, &_Py _ID(_errcheck_), &ob) < 0) {
2643         return -1;
2644     }
2645     if (ob) {
2646         if (!PyCallable_Check(ob)) {
2647             PyErr_SetString(PyExc_TypeError,
2648                 "_errcheck_ must be callable");
2649             Py_DECREF(ob);
2650             return -1;
2651         }
2652         stginfo->errcheck = ob;
2653     }
2654 */
2655     return 0;
2656 }
2657 
2658 static PyCArgObject *
PyCFuncPtrType_paramfunc(ctypes_state * st,CDataObject * self)2659 PyCFuncPtrType_paramfunc(ctypes_state *st, CDataObject *self)
2660 {
2661     PyCArgObject *parg;
2662 
2663     parg = PyCArgObject_new(st);
2664     if (parg == NULL)
2665         return NULL;
2666 
2667     parg->tag = 'P';
2668     parg->pffi_type = &ffi_type_pointer;
2669     parg->obj = Py_NewRef(self);
2670     parg->value.p = *(void **)self->b_ptr;
2671     return parg;
2672 }
2673 
2674 static int
PyCFuncPtrType_init(PyObject * self,PyObject * args,PyObject * kwds)2675 PyCFuncPtrType_init(PyObject *self, PyObject *args, PyObject *kwds)
2676 {
2677     PyObject *attrdict = PyType_GetDict((PyTypeObject *)self);
2678     if (!attrdict) {
2679         return -1;
2680     }
2681 
2682     ctypes_state *st = get_module_state_by_def(Py_TYPE(self));
2683     StgInfo *stginfo = PyStgInfo_Init(st, (PyTypeObject *)self);
2684     if (!stginfo) {
2685         Py_DECREF(attrdict);
2686         return -1;
2687     }
2688 
2689     stginfo->paramfunc = PyCFuncPtrType_paramfunc;
2690 
2691     /* We do NOT expose the function signature in the format string.  It
2692        is impossible, generally, because the only requirement for the
2693        argtypes items is that they have a .from_param method - we do not
2694        know the types of the arguments (although, in practice, most
2695        argtypes would be a ctypes type).
2696     */
2697     stginfo->format = _ctypes_alloc_format_string(NULL, "X{}");
2698     if (stginfo->format == NULL) {
2699         Py_DECREF(attrdict);
2700         return -1;
2701     }
2702     stginfo->flags |= TYPEFLAG_ISPOINTER;
2703 
2704     if (make_funcptrtype_dict(st, attrdict, stginfo) < 0) {
2705         Py_DECREF(attrdict);
2706         return -1;
2707     }
2708 
2709     Py_DECREF(attrdict);
2710     return 0;
2711 }
2712 
2713 static PyType_Slot pycfuncptr_type_slots[] = {
2714     {Py_tp_doc, PyDoc_STR("metatype for C function pointers")},
2715     {Py_tp_methods, CDataType_methods},
2716     {Py_tp_init, PyCFuncPtrType_init},
2717     {0, NULL},
2718 };
2719 
2720 static PyType_Spec pycfuncptr_type_spec = {
2721     .name = "_ctypes.PyCFuncPtrType",
2722     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2723               Py_TPFLAGS_IMMUTABLETYPE),
2724     .slots = pycfuncptr_type_slots,
2725 };
2726 
2727 
2728 /*****************************************************************
2729  * Code to keep needed objects alive
2730  */
2731 
2732 static CDataObject *
PyCData_GetContainer(CDataObject * self)2733 PyCData_GetContainer(CDataObject *self)
2734 {
2735     while (self->b_base)
2736         self = self->b_base;
2737     if (self->b_objects == NULL) {
2738         if (self->b_length) {
2739             self->b_objects = PyDict_New();
2740             if (self->b_objects == NULL)
2741                 return NULL;
2742         } else {
2743             self->b_objects = Py_NewRef(Py_None);
2744         }
2745     }
2746     return self;
2747 }
2748 
2749 static PyObject *
GetKeepedObjects(CDataObject * target)2750 GetKeepedObjects(CDataObject *target)
2751 {
2752     CDataObject *container;
2753     container = PyCData_GetContainer(target);
2754     if (container == NULL)
2755         return NULL;
2756     return container->b_objects;
2757 }
2758 
2759 static PyObject *
unique_key(CDataObject * target,Py_ssize_t index)2760 unique_key(CDataObject *target, Py_ssize_t index)
2761 {
2762     char string[256];
2763     char *cp = string;
2764     size_t bytes_left;
2765 
2766     Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2);
2767     cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2768     while (target->b_base) {
2769         bytes_left = sizeof(string) - (cp - string) - 1;
2770         /* Hex format needs 2 characters per byte */
2771         if (bytes_left < sizeof(Py_ssize_t) * 2) {
2772             PyErr_SetString(PyExc_ValueError,
2773                             "ctypes object structure too deep");
2774             return NULL;
2775         }
2776         cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
2777         target = target->b_base;
2778     }
2779     return PyUnicode_FromStringAndSize(string, cp-string);
2780 }
2781 
2782 /*
2783  * Keep a reference to 'keep' in the 'target', at index 'index'.
2784  *
2785  * If 'keep' is None, do nothing.
2786  *
2787  * Otherwise create a dictionary (if it does not yet exist) id the root
2788  * objects 'b_objects' item, which will store the 'keep' object under a unique
2789  * key.
2790  *
2791  * The unique_key helper travels the target's b_base pointer down to the root,
2792  * building a string containing hex-formatted indexes found during traversal,
2793  * separated by colons.
2794  *
2795  * The index tuple is used as a key into the root object's b_objects dict.
2796  *
2797  * Note: This function steals a refcount of the third argument, even if it
2798  * fails!
2799  */
2800 static int
KeepRef(CDataObject * target,Py_ssize_t index,PyObject * keep)2801 KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep)
2802 {
2803     int result;
2804     CDataObject *ob;
2805     PyObject *key;
2806 
2807 /* Optimization: no need to store None */
2808     if (keep == Py_None) {
2809         Py_DECREF(Py_None);
2810         return 0;
2811     }
2812     ob = PyCData_GetContainer(target);
2813     if (ob == NULL) {
2814         Py_DECREF(keep);
2815         return -1;
2816     }
2817     if (ob->b_objects == NULL || !PyDict_CheckExact(ob->b_objects)) {
2818         Py_XSETREF(ob->b_objects, keep); /* refcount consumed */
2819         return 0;
2820     }
2821     key = unique_key(target, index);
2822     if (key == NULL) {
2823         Py_DECREF(keep);
2824         return -1;
2825     }
2826     result = PyDict_SetItem(ob->b_objects, key, keep);
2827     Py_DECREF(key);
2828     Py_DECREF(keep);
2829     return result;
2830 }
2831 
2832 /******************************************************************/
2833 /*
2834   PyCData_Type
2835  */
2836 
2837 /*[clinic input]
2838 class _ctypes.PyCData "PyObject *" "clinic_state()->PyCData_Type"
2839 [clinic start generated code]*/
2840 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ac13df38dee3c22c]*/
2841 
2842 
2843 static int
PyCData_traverse(CDataObject * self,visitproc visit,void * arg)2844 PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
2845 {
2846     Py_VISIT(self->b_objects);
2847     Py_VISIT((PyObject *)self->b_base);
2848     PyTypeObject *type = Py_TYPE(self);
2849     Py_VISIT(type);
2850     return 0;
2851 }
2852 
2853 static int
PyCData_clear(CDataObject * self)2854 PyCData_clear(CDataObject *self)
2855 {
2856     Py_CLEAR(self->b_objects);
2857     if ((self->b_needsfree)
2858         && _CDataObject_HasExternalBuffer(self))
2859         PyMem_Free(self->b_ptr);
2860     self->b_ptr = NULL;
2861     Py_CLEAR(self->b_base);
2862     return 0;
2863 }
2864 
2865 static void
PyCData_dealloc(PyObject * self)2866 PyCData_dealloc(PyObject *self)
2867 {
2868     PyTypeObject *type = Py_TYPE(self);
2869     PyObject_GC_UnTrack(self);
2870     PyCData_clear((CDataObject *)self);
2871     type->tp_free(self);
2872     Py_DECREF(type);
2873 }
2874 
2875 static PyMemberDef PyCData_members[] = {
2876     { "_b_base_", _Py_T_OBJECT,
2877       offsetof(CDataObject, b_base), Py_READONLY,
2878       "the base object" },
2879     { "_b_needsfree_", Py_T_INT,
2880       offsetof(CDataObject, b_needsfree), Py_READONLY,
2881       "whether the object owns the memory or not" },
2882     { "_objects", _Py_T_OBJECT,
2883       offsetof(CDataObject, b_objects), Py_READONLY,
2884       "internal objects tree (NEVER CHANGE THIS OBJECT!)"},
2885     { NULL },
2886 };
2887 
2888 /* Find the innermost type of an array type, returning a borrowed reference */
2889 static PyObject *
PyCData_item_type(ctypes_state * st,PyObject * type)2890 PyCData_item_type(ctypes_state *st, PyObject *type)
2891 {
2892     if (PyCArrayTypeObject_Check(st, type)) {
2893         PyObject *elem_type;
2894 
2895         /* asserts used here as these are all guaranteed by construction */
2896         StgInfo *stg_info;
2897         if (PyStgInfo_FromType(st, type, &stg_info) < 0) {
2898             return NULL;
2899         }
2900         assert(stg_info);
2901         elem_type = stg_info->proto;
2902         assert(elem_type);
2903         return PyCData_item_type(st, elem_type);
2904     }
2905     else {
2906         return type;
2907     }
2908 }
2909 
2910 static int
PyCData_NewGetBuffer(PyObject * myself,Py_buffer * view,int flags)2911 PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
2912 {
2913     CDataObject *self = (CDataObject *)myself;
2914 
2915     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
2916     StgInfo *info;
2917     if (PyStgInfo_FromObject(st, myself, &info) < 0) {
2918         return -1;
2919     }
2920     assert(info);
2921 
2922     PyObject *item_type = PyCData_item_type(st, (PyObject*)Py_TYPE(myself));
2923     if (item_type == NULL) {
2924         return 0;
2925     }
2926 
2927     if (view == NULL) return 0;
2928 
2929     StgInfo *item_info;
2930     if (PyStgInfo_FromType(st, item_type, &item_info) < 0) {
2931         return -1;
2932     }
2933     assert(item_info);
2934 
2935     view->buf = self->b_ptr;
2936     view->obj = Py_NewRef(myself);
2937     view->len = self->b_size;
2938     view->readonly = 0;
2939     /* use default format character if not set */
2940     view->format = info->format ? info->format : "B";
2941     view->ndim = info->ndim;
2942     view->shape = info->shape;
2943     view->itemsize = item_info->size;
2944     view->strides = NULL;
2945     view->suboffsets = NULL;
2946     view->internal = NULL;
2947     return 0;
2948 }
2949 
2950 /*
2951  * CData objects are mutable, so they cannot be hashable!
2952  */
2953 static Py_hash_t
PyCData_nohash(PyObject * self)2954 PyCData_nohash(PyObject *self)
2955 {
2956     PyErr_SetString(PyExc_TypeError, "unhashable type");
2957     return -1;
2958 }
2959 
2960 /*[clinic input]
2961 _ctypes.PyCData.__reduce__ as PyCData_reduce
2962 
2963     myself: self
2964     cls: defining_class
2965     /
2966 [clinic start generated code]*/
2967 
2968 static PyObject *
PyCData_reduce_impl(PyObject * myself,PyTypeObject * cls)2969 PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
2970 /*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
2971 {
2972     CDataObject *self = (CDataObject *)myself;
2973 
2974     ctypes_state *st = get_module_state_by_class(cls);
2975     StgInfo *info;
2976     if (PyStgInfo_FromObject(st, myself, &info) < 0) {
2977         return NULL;
2978     }
2979     assert(info);
2980 
2981     if (info->flags & (TYPEFLAG_ISPOINTER|TYPEFLAG_HASPOINTER)) {
2982         PyErr_SetString(PyExc_ValueError,
2983                         "ctypes objects containing pointers cannot be pickled");
2984         return NULL;
2985     }
2986     PyObject *dict = PyObject_GetAttrString(myself, "__dict__");
2987     if (dict == NULL) {
2988         return NULL;
2989     }
2990     return Py_BuildValue("O(O(NN))", st->_unpickle, Py_TYPE(myself), dict,
2991                          PyBytes_FromStringAndSize(self->b_ptr, self->b_size));
2992 }
2993 
2994 static PyObject *
PyCData_setstate(PyObject * myself,PyObject * args)2995 PyCData_setstate(PyObject *myself, PyObject *args)
2996 {
2997     void *data;
2998     Py_ssize_t len;
2999     int res;
3000     PyObject *dict, *mydict;
3001     CDataObject *self = (CDataObject *)myself;
3002     if (!PyArg_ParseTuple(args, "O!s#",
3003                           &PyDict_Type, &dict, &data, &len))
3004     {
3005         return NULL;
3006     }
3007     if (len > self->b_size)
3008         len = self->b_size;
3009     memmove(self->b_ptr, data, len);
3010     mydict = PyObject_GetAttrString(myself, "__dict__");
3011     if (mydict == NULL) {
3012         return NULL;
3013     }
3014     if (!PyDict_Check(mydict)) {
3015         PyErr_Format(PyExc_TypeError,
3016                      "%.200s.__dict__ must be a dictionary, not %.200s",
3017                      Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name);
3018         Py_DECREF(mydict);
3019         return NULL;
3020     }
3021     res = PyDict_Update(mydict, dict);
3022     Py_DECREF(mydict);
3023     if (res == -1)
3024         return NULL;
3025     Py_RETURN_NONE;
3026 }
3027 
3028 /*
3029  * default __ctypes_from_outparam__ method returns self.
3030  */
3031 static PyObject *
PyCData_from_outparam(PyObject * self,PyObject * args)3032 PyCData_from_outparam(PyObject *self, PyObject *args)
3033 {
3034     return Py_NewRef(self);
3035 }
3036 
3037 static PyMethodDef PyCData_methods[] = {
3038     { "__ctypes_from_outparam__", PyCData_from_outparam, METH_NOARGS, },
3039     PYCDATA_REDUCE_METHODDEF
3040     { "__setstate__", PyCData_setstate, METH_VARARGS, },
3041     { NULL, NULL },
3042 };
3043 
3044 static PyType_Slot pycdata_slots[] = {
3045     {Py_tp_dealloc, PyCData_dealloc},
3046     {Py_tp_hash, PyCData_nohash},
3047     {Py_tp_doc, PyDoc_STR("XXX to be provided")},
3048     {Py_tp_traverse, PyCData_traverse},
3049     {Py_tp_clear, PyCData_clear},
3050     {Py_tp_methods, PyCData_methods},
3051     {Py_tp_members, PyCData_members},
3052     {Py_bf_getbuffer, PyCData_NewGetBuffer},
3053     {0, NULL},
3054 };
3055 
3056 static PyType_Spec pycdata_spec = {
3057     .name = "_ctypes._CData",
3058     .basicsize = sizeof(CDataObject),
3059     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
3060               Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
3061     .slots = pycdata_slots,
3062 };
3063 
3064 static int
PyCData_MallocBuffer(CDataObject * obj,StgInfo * info)3065 PyCData_MallocBuffer(CDataObject *obj, StgInfo *info)
3066 {
3067     if ((size_t)info->size <= sizeof(obj->b_value)) {
3068         /* No need to call malloc, can use the default buffer */
3069         obj->b_ptr = (char *)&obj->b_value;
3070         /* The b_needsfree flag does not mean that we actually did
3071            call PyMem_Malloc to allocate the memory block; instead it
3072            means we are the *owner* of the memory and are responsible
3073            for freeing resources associated with the memory.  This is
3074            also the reason that b_needsfree is exposed to Python.
3075          */
3076         obj->b_needsfree = 1;
3077     } else {
3078         /* In python 2.4, and ctypes 0.9.6, the malloc call took about
3079            33% of the creation time for c_int().
3080         */
3081         obj->b_ptr = (char *)PyMem_Malloc(info->size);
3082         if (obj->b_ptr == NULL) {
3083             PyErr_NoMemory();
3084             return -1;
3085         }
3086         obj->b_needsfree = 1;
3087         memset(obj->b_ptr, 0, info->size);
3088     }
3089     obj->b_size = info->size;
3090     return 0;
3091 }
3092 
3093 PyObject *
PyCData_FromBaseObj(ctypes_state * st,PyObject * type,PyObject * base,Py_ssize_t index,char * adr)3094 PyCData_FromBaseObj(ctypes_state *st,
3095                     PyObject *type, PyObject *base, Py_ssize_t index, char *adr)
3096 {
3097     CDataObject *cmem;
3098 
3099     assert(PyType_Check(type));
3100 
3101     StgInfo *info;
3102     if (PyStgInfo_FromType(st, type, &info) < 0) {
3103         return NULL;
3104     }
3105     if (!info) {
3106         PyErr_SetString(PyExc_TypeError,
3107                         "abstract class");
3108         return NULL;
3109     }
3110 
3111     info->flags |= DICTFLAG_FINAL;
3112     cmem = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
3113     if (cmem == NULL) {
3114         return NULL;
3115     }
3116     assert(CDataObject_Check(st, cmem));
3117     cmem->b_length = info->length;
3118     cmem->b_size = info->size;
3119     if (base) { /* use base's buffer */
3120         assert(CDataObject_Check(st, base));
3121         cmem->b_ptr = adr;
3122         cmem->b_needsfree = 0;
3123         cmem->b_base = (CDataObject *)Py_NewRef(base);
3124         cmem->b_index = index;
3125     } else { /* copy contents of adr */
3126         if (-1 == PyCData_MallocBuffer(cmem, info)) {
3127             Py_DECREF(cmem);
3128             return NULL;
3129         }
3130         memcpy(cmem->b_ptr, adr, info->size);
3131         cmem->b_index = index;
3132     }
3133     return (PyObject *)cmem;
3134 }
3135 
3136 /*
3137  Box a memory block into a CData instance.
3138 */
3139 PyObject *
PyCData_AtAddress(ctypes_state * st,PyObject * type,void * buf)3140 PyCData_AtAddress(ctypes_state *st, PyObject *type, void *buf)
3141 {
3142     CDataObject *pd;
3143 
3144     if (PySys_Audit("ctypes.cdata", "n", (Py_ssize_t)buf) < 0) {
3145         return NULL;
3146     }
3147 
3148     assert(PyType_Check(type));
3149 
3150     StgInfo *info;
3151     if (PyStgInfo_FromType(st, type, &info) < 0) {
3152         return NULL;
3153     }
3154     if (!info) {
3155         PyErr_SetString(PyExc_TypeError,
3156                         "abstract class");
3157         return NULL;
3158     }
3159 
3160     info->flags |= DICTFLAG_FINAL;
3161 
3162     pd = (CDataObject *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0);
3163     if (!pd) {
3164         return NULL;
3165     }
3166     assert(CDataObject_Check(st, pd));
3167     pd->b_ptr = (char *)buf;
3168     pd->b_length = info->length;
3169     pd->b_size = info->size;
3170     return (PyObject *)pd;
3171 }
3172 
3173 /*
3174   This function returns TRUE for c_int, c_void_p, and these kind of
3175   classes.  FALSE otherwise FALSE also for subclasses of c_int and
3176   such.
3177 */
_ctypes_simple_instance(ctypes_state * st,PyObject * obj)3178 int _ctypes_simple_instance(ctypes_state *st, PyObject *obj)
3179 {
3180     PyTypeObject *type = (PyTypeObject *)obj;
3181 
3182     if (PyCSimpleTypeObject_Check(st, type)) {
3183         return type->tp_base != st->Simple_Type;
3184     }
3185     return 0;
3186 }
3187 
3188 PyObject *
PyCData_get(ctypes_state * st,PyObject * type,GETFUNC getfunc,PyObject * src,Py_ssize_t index,Py_ssize_t size,char * adr)3189 PyCData_get(ctypes_state *st, PyObject *type, GETFUNC getfunc, PyObject *src,
3190           Py_ssize_t index, Py_ssize_t size, char *adr)
3191 {
3192     if (getfunc)
3193         return getfunc(adr, size);
3194     assert(type);
3195     StgInfo *info;
3196     if (PyStgInfo_FromType(st, type, &info) < 0) {
3197         return NULL;
3198     }
3199     if (info && info->getfunc && !_ctypes_simple_instance(st, type)) {
3200         return info->getfunc(adr, size);
3201     }
3202     return PyCData_FromBaseObj(st, type, src, index, adr);
3203 }
3204 
3205 /*
3206   Helper function for PyCData_set below.
3207 */
3208 static PyObject *
_PyCData_set(ctypes_state * st,CDataObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t size,char * ptr)3209 _PyCData_set(ctypes_state *st,
3210            CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3211            Py_ssize_t size, char *ptr)
3212 {
3213     CDataObject *src;
3214     int err;
3215 
3216     if (setfunc) {
3217         return setfunc(ptr, value, size);
3218     }
3219     if (!CDataObject_Check(st, value)) {
3220         StgInfo *info;
3221         if (PyStgInfo_FromType(st, type, &info) < 0) {
3222             return NULL;
3223         }
3224         if (info && info->setfunc)
3225             return info->setfunc(ptr, value, size);
3226         /*
3227            If value is a tuple, we try to call the type with the tuple
3228            and use the result!
3229         */
3230         assert(PyType_Check(type));
3231         if (PyTuple_Check(value)) {
3232             PyObject *ob;
3233             PyObject *result;
3234             ob = PyObject_CallObject(type, value);
3235             if (ob == NULL) {
3236                 _ctypes_extend_error(PyExc_RuntimeError, "(%s) ",
3237                                   ((PyTypeObject *)type)->tp_name);
3238                 return NULL;
3239             }
3240             result = _PyCData_set(st, dst, type, setfunc, ob,
3241                                 size, ptr);
3242             Py_DECREF(ob);
3243             return result;
3244         } else if (value == Py_None && PyCPointerTypeObject_Check(st, type)) {
3245             *(void **)ptr = NULL;
3246             Py_RETURN_NONE;
3247         } else {
3248             PyErr_Format(PyExc_TypeError,
3249                          "expected %s instance, got %s",
3250                          ((PyTypeObject *)type)->tp_name,
3251                          Py_TYPE(value)->tp_name);
3252             return NULL;
3253         }
3254     }
3255     src = (CDataObject *)value;
3256 
3257     err = PyObject_IsInstance(value, type);
3258     if (err == -1)
3259         return NULL;
3260     if (err) {
3261         memcpy(ptr,
3262                src->b_ptr,
3263                size);
3264 
3265         if (PyCPointerTypeObject_Check(st, type)) {
3266             /* XXX */
3267         }
3268 
3269         value = GetKeepedObjects(src);
3270         if (value == NULL)
3271             return NULL;
3272 
3273         return Py_NewRef(value);
3274     }
3275 
3276     if (PyCPointerTypeObject_Check(st, type)
3277         && ArrayObject_Check(st, value)) {
3278         PyObject *keep;
3279 
3280         StgInfo *p1, *p2;
3281         if (PyStgInfo_FromObject(st, value, &p1) < 0) {
3282             return NULL;
3283         }
3284         assert(p1); /* Cannot be NULL for array instances */
3285         if (PyStgInfo_FromType(st, type, &p2) < 0) {
3286             return NULL;
3287         }
3288         assert(p2); /* Cannot be NULL for pointer types */
3289 
3290         if (p1->proto != p2->proto) {
3291             PyErr_Format(PyExc_TypeError,
3292                          "incompatible types, %s instance instead of %s instance",
3293                          Py_TYPE(value)->tp_name,
3294                          ((PyTypeObject *)type)->tp_name);
3295             return NULL;
3296         }
3297         *(void **)ptr = src->b_ptr;
3298 
3299         keep = GetKeepedObjects(src);
3300         if (keep == NULL)
3301             return NULL;
3302 
3303         /*
3304           We are assigning an array object to a field which represents
3305           a pointer. This has the same effect as converting an array
3306           into a pointer. So, again, we have to keep the whole object
3307           pointed to (which is the array in this case) alive, and not
3308           only it's object list.  So we create a tuple, containing
3309           b_objects list PLUS the array itself, and return that!
3310         */
3311         return PyTuple_Pack(2, keep, value);
3312     }
3313     PyErr_Format(PyExc_TypeError,
3314                  "incompatible types, %s instance instead of %s instance",
3315                  Py_TYPE(value)->tp_name,
3316                  ((PyTypeObject *)type)->tp_name);
3317     return NULL;
3318 }
3319 
3320 /*
3321  * Set a slice in object 'dst', which has the type 'type',
3322  * to the value 'value'.
3323  */
3324 int
PyCData_set(ctypes_state * st,PyObject * dst,PyObject * type,SETFUNC setfunc,PyObject * value,Py_ssize_t index,Py_ssize_t size,char * ptr)3325 PyCData_set(ctypes_state *st,
3326           PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value,
3327           Py_ssize_t index, Py_ssize_t size, char *ptr)
3328 {
3329     CDataObject *mem = (CDataObject *)dst;
3330     PyObject *result;
3331 
3332     if (!CDataObject_Check(st, dst)) {
3333         PyErr_SetString(PyExc_TypeError,
3334                         "not a ctype instance");
3335         return -1;
3336     }
3337 
3338     result = _PyCData_set(st, mem, type, setfunc, value,
3339                         size, ptr);
3340     if (result == NULL)
3341         return -1;
3342 
3343     /* KeepRef steals a refcount from it's last argument */
3344     /* If KeepRef fails, we are stumped.  The dst memory block has already
3345        been changed */
3346     return KeepRef(mem, index, result);
3347 }
3348 
3349 
3350 /******************************************************************/
3351 static PyObject *
GenericPyCData_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3352 GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3353 {
3354     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
3355     return generic_pycdata_new(st, type, args, kwds);
3356 }
3357 
3358 static inline PyObject *
generic_pycdata_new(ctypes_state * st,PyTypeObject * type,PyObject * args,PyObject * kwds)3359 generic_pycdata_new(ctypes_state *st,
3360                     PyTypeObject *type, PyObject *args, PyObject *kwds)
3361 {
3362     CDataObject *obj;
3363 
3364     StgInfo *info;
3365     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
3366         return NULL;
3367     }
3368     if (!info) {
3369         PyErr_SetString(PyExc_TypeError,
3370                         "abstract class");
3371         return NULL;
3372     }
3373 
3374     info->flags |= DICTFLAG_FINAL;
3375 
3376     obj = (CDataObject *)type->tp_alloc(type, 0);
3377     if (!obj)
3378         return NULL;
3379 
3380     obj->b_base = NULL;
3381     obj->b_index = 0;
3382     obj->b_objects = NULL;
3383     obj->b_length = info->length;
3384 
3385     if (-1 == PyCData_MallocBuffer(obj, info)) {
3386         Py_DECREF(obj);
3387         return NULL;
3388     }
3389     return (PyObject *)obj;
3390 }
3391 /*****************************************************************/
3392 /*
3393   PyCFuncPtr_Type
3394 */
3395 
3396 static int
PyCFuncPtr_set_errcheck(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3397 PyCFuncPtr_set_errcheck(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3398 {
3399     if (ob && !PyCallable_Check(ob)) {
3400         PyErr_SetString(PyExc_TypeError,
3401                         "the errcheck attribute must be callable");
3402         return -1;
3403     }
3404     Py_XINCREF(ob);
3405     Py_XSETREF(self->errcheck, ob);
3406     return 0;
3407 }
3408 
3409 static PyObject *
PyCFuncPtr_get_errcheck(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3410 PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3411 {
3412     if (self->errcheck) {
3413         return Py_NewRef(self->errcheck);
3414     }
3415     Py_RETURN_NONE;
3416 }
3417 
3418 static int
PyCFuncPtr_set_restype(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3419 PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3420 {
3421     PyObject *checker, *oldchecker;
3422     if (ob == NULL) {
3423         oldchecker = self->checker;
3424         self->checker = NULL;
3425         Py_CLEAR(self->restype);
3426         Py_XDECREF(oldchecker);
3427         return 0;
3428     }
3429     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
3430     StgInfo *info;
3431     if (PyStgInfo_FromType(st, ob, &info) < 0) {
3432         return -1;
3433     }
3434     if (ob != Py_None && !info && !PyCallable_Check(ob)) {
3435         PyErr_SetString(PyExc_TypeError,
3436                         "restype must be a type, a callable, or None");
3437         return -1;
3438     }
3439     if (PyObject_GetOptionalAttr(ob, &_Py_ID(_check_retval_), &checker) < 0) {
3440         return -1;
3441     }
3442     oldchecker = self->checker;
3443     self->checker = checker;
3444     Py_INCREF(ob);
3445     Py_XSETREF(self->restype, ob);
3446     Py_XDECREF(oldchecker);
3447     return 0;
3448 }
3449 
3450 static PyObject *
PyCFuncPtr_get_restype(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3451 PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3452 {
3453     if (self->restype) {
3454         return Py_NewRef(self->restype);
3455     }
3456     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
3457     StgInfo *info;
3458     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
3459         return NULL;
3460     }
3461     assert(info); /* Cannot be NULL for PyCFuncPtrObject instances */
3462     if (info->restype) {
3463         return Py_NewRef(info->restype);
3464     } else {
3465         Py_RETURN_NONE;
3466     }
3467 }
3468 
3469 static int
PyCFuncPtr_set_argtypes(PyCFuncPtrObject * self,PyObject * ob,void * Py_UNUSED (ignored))3470 PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
3471 {
3472     PyObject *converters;
3473 
3474     if (ob == NULL || ob == Py_None) {
3475         Py_CLEAR(self->converters);
3476         Py_CLEAR(self->argtypes);
3477     } else {
3478         ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
3479         converters = converters_from_argtypes(st, ob);
3480         if (!converters)
3481             return -1;
3482         Py_XSETREF(self->converters, converters);
3483         Py_INCREF(ob);
3484         Py_XSETREF(self->argtypes, ob);
3485     }
3486     return 0;
3487 }
3488 
3489 static PyObject *
PyCFuncPtr_get_argtypes(PyCFuncPtrObject * self,void * Py_UNUSED (ignored))3490 PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
3491 {
3492     if (self->argtypes) {
3493         return Py_NewRef(self->argtypes);
3494     }
3495     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
3496     StgInfo *info;
3497     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
3498         return NULL;
3499     }
3500     assert(info); /* Cannot be NULL for PyCFuncPtrObject instances */
3501     if (info->argtypes) {
3502         return Py_NewRef(info->argtypes);
3503     } else {
3504         Py_RETURN_NONE;
3505     }
3506 }
3507 
3508 static PyGetSetDef PyCFuncPtr_getsets[] = {
3509     { "errcheck", (getter)PyCFuncPtr_get_errcheck, (setter)PyCFuncPtr_set_errcheck,
3510       "a function to check for errors", NULL },
3511     { "restype", (getter)PyCFuncPtr_get_restype, (setter)PyCFuncPtr_set_restype,
3512       "specify the result type", NULL },
3513     { "argtypes", (getter)PyCFuncPtr_get_argtypes,
3514       (setter)PyCFuncPtr_set_argtypes,
3515       "specify the argument types", NULL },
3516     { NULL, NULL }
3517 };
3518 
3519 #ifdef MS_WIN32
FindAddress(void * handle,const char * name,PyObject * type)3520 static PPROC FindAddress(void *handle, const char *name, PyObject *type)
3521 {
3522     PPROC address;
3523 #ifdef MS_WIN64
3524     /* win64 has no stdcall calling conv, so it should
3525        also not have the name mangling of it.
3526     */
3527     Py_BEGIN_ALLOW_THREADS
3528     address = (PPROC)GetProcAddress(handle, name);
3529     Py_END_ALLOW_THREADS
3530     return address;
3531 #else
3532     char *mangled_name;
3533     int i;
3534 
3535     Py_BEGIN_ALLOW_THREADS
3536     address = (PPROC)GetProcAddress(handle, name);
3537     Py_END_ALLOW_THREADS
3538     if (address)
3539         return address;
3540     if (((size_t)name & ~0xFFFF) == 0) {
3541         return NULL;
3542     }
3543 
3544     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
3545     StgInfo *info;
3546     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
3547         return NULL;
3548     }
3549     /* It should not happen that info is NULL, but better be safe */
3550     if (info==NULL || info->flags & FUNCFLAG_CDECL)
3551         return address;
3552 
3553     /* for stdcall, try mangled names:
3554        funcname -> _funcname@<n>
3555        where n is 0, 4, 8, 12, ..., 128
3556      */
3557     mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
3558     if (!mangled_name)
3559         return NULL;
3560     for (i = 0; i < 32; ++i) {
3561         sprintf(mangled_name, "_%s@%d", name, i*4);
3562         Py_BEGIN_ALLOW_THREADS
3563         address = (PPROC)GetProcAddress(handle, mangled_name);
3564         Py_END_ALLOW_THREADS
3565         if (address)
3566             return address;
3567     }
3568     return NULL;
3569 #endif
3570 }
3571 #endif
3572 
3573 /* Return 1 if usable, 0 else and exception set. */
3574 static int
_check_outarg_type(ctypes_state * st,PyObject * arg,Py_ssize_t index)3575 _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
3576 {
3577     if (PyCPointerTypeObject_Check(st, arg)) {
3578         return 1;
3579     }
3580     if (PyCArrayTypeObject_Check(st, arg)) {
3581         return 1;
3582     }
3583     StgInfo *info;
3584     if (PyStgInfo_FromType(st, arg, &info) < 0) {
3585         return -1;
3586     }
3587     if (info
3588         /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
3589         && PyUnicode_Check(info->proto)
3590 /* We only allow c_void_p, c_char_p and c_wchar_p as a simple output parameter type */
3591         && (strchr("PzZ", PyUnicode_AsUTF8(info->proto)[0]))) {
3592         return 1;
3593     }
3594 
3595     PyErr_Format(PyExc_TypeError,
3596                  "'out' parameter %d must be a pointer type, not %s",
3597                  Py_SAFE_DOWNCAST(index, Py_ssize_t, int),
3598                  PyType_Check(arg) ?
3599                  ((PyTypeObject *)arg)->tp_name :
3600              Py_TYPE(arg)->tp_name);
3601     return 0;
3602 }
3603 
3604 /* Returns 1 on success, 0 on error */
3605 static int
_validate_paramflags(ctypes_state * st,PyTypeObject * type,PyObject * paramflags)3606 _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
3607 {
3608     Py_ssize_t i, len;
3609     PyObject *argtypes;
3610 
3611     StgInfo *info;
3612     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
3613         return -1;
3614     }
3615     if (!info) {
3616         PyErr_SetString(PyExc_TypeError,
3617                         "abstract class");
3618         return 0;
3619     }
3620     argtypes = info->argtypes;
3621 
3622     if (paramflags == NULL || info->argtypes == NULL)
3623         return 1;
3624 
3625     if (!PyTuple_Check(paramflags)) {
3626         PyErr_SetString(PyExc_TypeError,
3627                         "paramflags must be a tuple or None");
3628         return 0;
3629     }
3630 
3631     len = PyTuple_GET_SIZE(paramflags);
3632     if (len != PyTuple_GET_SIZE(info->argtypes)) {
3633         PyErr_SetString(PyExc_ValueError,
3634                         "paramflags must have the same length as argtypes");
3635         return 0;
3636     }
3637 
3638     for (i = 0; i < len; ++i) {
3639         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
3640         int flag;
3641         PyObject *name = Py_None;
3642         PyObject *defval;
3643         PyObject *typ;
3644         if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) ||
3645             !(name == Py_None || PyUnicode_Check(name)))
3646         {
3647             PyErr_SetString(PyExc_TypeError,
3648                    "paramflags must be a sequence of (int [,string [,value]]) tuples");
3649             return 0;
3650         }
3651         typ = PyTuple_GET_ITEM(argtypes, i);
3652         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
3653         case 0:
3654         case PARAMFLAG_FIN:
3655         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
3656         case PARAMFLAG_FIN | PARAMFLAG_FOUT:
3657             break;
3658         case PARAMFLAG_FOUT:
3659             if (!_check_outarg_type(st, typ, i+1))
3660                 return 0;
3661             break;
3662         default:
3663             PyErr_Format(PyExc_TypeError,
3664                          "paramflag value %d not supported",
3665                          flag);
3666             return 0;
3667         }
3668     }
3669     return 1;
3670 }
3671 
3672 static int
_get_name(PyObject * obj,const char ** pname)3673 _get_name(PyObject *obj, const char **pname)
3674 {
3675 #ifdef MS_WIN32
3676     if (PyLong_Check(obj)) {
3677         /* We have to use MAKEINTRESOURCEA for Windows CE.
3678            Works on Windows as well, of course.
3679         */
3680         *pname = MAKEINTRESOURCEA(PyLong_AsUnsignedLongMask(obj) & 0xFFFF);
3681         return 1;
3682     }
3683 #endif
3684     if (PyBytes_Check(obj)) {
3685         *pname = PyBytes_AS_STRING(obj);
3686         return *pname ? 1 : 0;
3687     }
3688     if (PyUnicode_Check(obj)) {
3689         *pname = PyUnicode_AsUTF8(obj);
3690         return *pname ? 1 : 0;
3691     }
3692     PyErr_SetString(PyExc_TypeError,
3693                     "function name must be string, bytes object or integer");
3694     return 0;
3695 }
3696 
3697 
3698 static PyObject *
PyCFuncPtr_FromDll(PyTypeObject * type,PyObject * args,PyObject * kwds)3699 PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
3700 {
3701     const char *name;
3702     int (* address)(void);
3703     PyObject *ftuple;
3704     PyObject *dll;
3705     PyObject *obj;
3706     PyCFuncPtrObject *self;
3707     void *handle;
3708     PyObject *paramflags = NULL;
3709 
3710     if (!PyArg_ParseTuple(args, "O|O", &ftuple, &paramflags))
3711         return NULL;
3712     if (paramflags == Py_None)
3713         paramflags = NULL;
3714 
3715     ftuple = PySequence_Tuple(ftuple);
3716     if (!ftuple)
3717         /* Here ftuple is a borrowed reference */
3718         return NULL;
3719 
3720     if (!PyArg_ParseTuple(ftuple, "O&O;illegal func_spec argument",
3721                           _get_name, &name, &dll))
3722     {
3723         Py_DECREF(ftuple);
3724         return NULL;
3725     }
3726 
3727 #ifdef MS_WIN32
3728     if (PySys_Audit("ctypes.dlsym",
3729                     ((uintptr_t)name & ~0xFFFF) ? "Os" : "On",
3730                     dll, name) < 0) {
3731         Py_DECREF(ftuple);
3732         return NULL;
3733     }
3734 #else
3735     if (PySys_Audit("ctypes.dlsym", "Os", dll, name) < 0) {
3736         Py_DECREF(ftuple);
3737         return NULL;
3738     }
3739 #endif
3740 
3741     obj = PyObject_GetAttrString(dll, "_handle");
3742     if (!obj) {
3743         Py_DECREF(ftuple);
3744         return NULL;
3745     }
3746     if (!PyLong_Check(obj)) {
3747         PyErr_SetString(PyExc_TypeError,
3748                         "the _handle attribute of the second argument must be an integer");
3749         Py_DECREF(ftuple);
3750         Py_DECREF(obj);
3751         return NULL;
3752     }
3753     handle = (void *)PyLong_AsVoidPtr(obj);
3754     Py_DECREF(obj);
3755     if (PyErr_Occurred()) {
3756         PyErr_SetString(PyExc_ValueError,
3757                         "could not convert the _handle attribute to a pointer");
3758         Py_DECREF(ftuple);
3759         return NULL;
3760     }
3761 
3762 #undef USE_DLERROR
3763 #ifdef MS_WIN32
3764     address = FindAddress(handle, name, (PyObject *)type);
3765     if (!address) {
3766         if (!IS_INTRESOURCE(name))
3767             PyErr_Format(PyExc_AttributeError,
3768                          "function '%s' not found",
3769                          name);
3770         else
3771             PyErr_Format(PyExc_AttributeError,
3772                          "function ordinal %d not found",
3773                          (WORD)(size_t)name);
3774         Py_DECREF(ftuple);
3775         return NULL;
3776     }
3777 #else
3778     #ifdef __CYGWIN__
3779         //dlerror() isn't very helpful on cygwin */
3780     #else
3781         #define USE_DLERROR
3782         /* dlerror() always returns the latest error.
3783          *
3784          * Clear the previous value before calling dlsym(),
3785          * to ensure we can tell if our call resulted in an error.
3786          */
3787         (void)dlerror();
3788     #endif
3789     address = (PPROC)dlsym(handle, name);
3790 
3791     if (!address) {
3792 	#ifdef USE_DLERROR
3793         const char *dlerr = dlerror();
3794         if (dlerr) {
3795             PyObject *message = PyUnicode_DecodeLocale(dlerr, "surrogateescape");
3796             if (message) {
3797                 PyErr_SetObject(PyExc_AttributeError, message);
3798                 Py_DECREF(ftuple);
3799                 Py_DECREF(message);
3800                 return NULL;
3801             }
3802             // Ignore errors from PyUnicode_DecodeLocale,
3803             // fall back to the generic error below.
3804             PyErr_Clear();
3805         }
3806 	#endif
3807         PyErr_Format(PyExc_AttributeError, "function '%s' not found", name);
3808         Py_DECREF(ftuple);
3809         return NULL;
3810     }
3811 #endif
3812 #undef USE_DLERROR
3813     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
3814     if (!_validate_paramflags(st, type, paramflags)) {
3815         Py_DECREF(ftuple);
3816         return NULL;
3817     }
3818 
3819     self = (PyCFuncPtrObject *)generic_pycdata_new(st, type, args, kwds);
3820     if (!self) {
3821         Py_DECREF(ftuple);
3822         return NULL;
3823     }
3824 
3825     self->paramflags = Py_XNewRef(paramflags);
3826 
3827     *(void **)self->b_ptr = address;
3828     Py_INCREF(dll);
3829     Py_DECREF(ftuple);
3830     if (-1 == KeepRef((CDataObject *)self, 0, dll)) {
3831         Py_DECREF((PyObject *)self);
3832         return NULL;
3833     }
3834 
3835     self->callable = Py_NewRef(self);
3836     return (PyObject *)self;
3837 }
3838 
3839 #ifdef MS_WIN32
3840 static PyObject *
PyCFuncPtr_FromVtblIndex(PyTypeObject * type,PyObject * args,PyObject * kwds)3841 PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
3842 {
3843     PyCFuncPtrObject *self;
3844     int index;
3845     char *name = NULL;
3846     PyObject *paramflags = NULL;
3847     GUID *iid = NULL;
3848     Py_ssize_t iid_len = 0;
3849 
3850     if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, &paramflags, &iid, &iid_len))
3851         return NULL;
3852     if (paramflags == Py_None)
3853         paramflags = NULL;
3854 
3855     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
3856     if (!_validate_paramflags(st, type, paramflags)) {
3857         return NULL;
3858     }
3859     self = (PyCFuncPtrObject *)generic_pycdata_new(st, type, args, kwds);
3860     self->index = index + 0x1000;
3861     self->paramflags = Py_XNewRef(paramflags);
3862     if (iid_len == sizeof(GUID))
3863         self->iid = iid;
3864     return (PyObject *)self;
3865 }
3866 #endif
3867 
3868 /*
3869   PyCFuncPtr_new accepts different argument lists in addition to the standard
3870   _basespec_ keyword arg:
3871 
3872   one argument form
3873   "i" - function address
3874   "O" - must be a callable, creates a C callable function
3875 
3876   two or more argument forms (the third argument is a paramflags tuple)
3877   "(sO)|..." - (function name, dll object (with an integer handle)), paramflags
3878   "(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
3879   "is|..." - vtable index, method name, creates callable calling COM vtbl
3880 */
3881 static PyObject *
PyCFuncPtr_new(PyTypeObject * type,PyObject * args,PyObject * kwds)3882 PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3883 {
3884     PyCFuncPtrObject *self;
3885     PyObject *callable;
3886     CThunkObject *thunk;
3887 
3888     if (PyTuple_GET_SIZE(args) == 0)
3889         return GenericPyCData_new(type, args, kwds);
3890 
3891     if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
3892         return PyCFuncPtr_FromDll(type, args, kwds);
3893 
3894 #ifdef MS_WIN32
3895     if (2 <= PyTuple_GET_SIZE(args) && PyLong_Check(PyTuple_GET_ITEM(args, 0)))
3896         return PyCFuncPtr_FromVtblIndex(type, args, kwds);
3897 #endif
3898 
3899     if (1 == PyTuple_GET_SIZE(args)
3900         && (PyLong_Check(PyTuple_GET_ITEM(args, 0)))) {
3901         CDataObject *ob;
3902         void *ptr = PyLong_AsVoidPtr(PyTuple_GET_ITEM(args, 0));
3903         if (ptr == NULL && PyErr_Occurred())
3904             return NULL;
3905         ob = (CDataObject *)GenericPyCData_new(type, args, kwds);
3906         if (ob == NULL)
3907             return NULL;
3908         *(void **)ob->b_ptr = ptr;
3909         return (PyObject *)ob;
3910     }
3911 
3912     if (!PyArg_ParseTuple(args, "O", &callable))
3913         return NULL;
3914     if (!PyCallable_Check(callable)) {
3915         PyErr_SetString(PyExc_TypeError,
3916                         "argument must be callable or integer function address");
3917         return NULL;
3918     }
3919 
3920     /* XXX XXX This would allow passing additional options.  For COM
3921        method *implementations*, we would probably want different
3922        behaviour than in 'normal' callback functions: return a HRESULT if
3923        an exception occurs in the callback, and print the traceback not
3924        only on the console, but also to OutputDebugString() or something
3925        like that.
3926     */
3927 /*
3928     if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) {
3929         ...
3930     }
3931     else if (PyErr_Occurred()) {
3932         return NULL;
3933     }
3934 */
3935 
3936     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
3937     StgInfo *info;
3938     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
3939         return NULL;
3940     }
3941     /* XXXX Fails if we do: 'PyCFuncPtr(lambda x: x)' */
3942     if (!info || !info->argtypes) {
3943         PyErr_SetString(PyExc_TypeError,
3944                "cannot construct instance of this class:"
3945             " no argtypes");
3946         return NULL;
3947     }
3948 
3949     thunk = _ctypes_alloc_callback(st,
3950                                   callable,
3951                                   info->argtypes,
3952                                   info->restype,
3953                                   info->flags);
3954     if (!thunk)
3955         return NULL;
3956 
3957     self = (PyCFuncPtrObject *)generic_pycdata_new(st, type, args, kwds);
3958     if (self == NULL) {
3959         Py_DECREF(thunk);
3960         return NULL;
3961     }
3962 
3963     self->callable = Py_NewRef(callable);
3964 
3965     self->thunk = thunk;
3966     *(void **)self->b_ptr = (void *)thunk->pcl_exec;
3967 
3968     Py_INCREF((PyObject *)thunk); /* for KeepRef */
3969     if (-1 == KeepRef((CDataObject *)self, 0, (PyObject *)thunk)) {
3970         Py_DECREF((PyObject *)self);
3971         return NULL;
3972     }
3973     return (PyObject *)self;
3974 }
3975 
3976 
3977 /*
3978   _byref consumes a refcount to its argument
3979 */
3980 static PyObject *
_byref(ctypes_state * st,PyObject * obj)3981 _byref(ctypes_state *st, PyObject *obj)
3982 {
3983     PyCArgObject *parg;
3984 
3985     if (!CDataObject_Check(st, obj)) {
3986         PyErr_SetString(PyExc_TypeError,
3987                         "expected CData instance");
3988         return NULL;
3989     }
3990 
3991     parg = PyCArgObject_new(st);
3992     if (parg == NULL) {
3993         Py_DECREF(obj);
3994         return NULL;
3995     }
3996 
3997     parg->tag = 'P';
3998     parg->pffi_type = &ffi_type_pointer;
3999     parg->obj = obj;
4000     parg->value.p = ((CDataObject *)obj)->b_ptr;
4001     return (PyObject *)parg;
4002 }
4003 
4004 static PyObject *
_get_arg(int * pindex,PyObject * name,PyObject * defval,PyObject * inargs,PyObject * kwds)4005 _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObject *kwds)
4006 {
4007     PyObject *v;
4008 
4009     if (*pindex < PyTuple_GET_SIZE(inargs)) {
4010         v = PyTuple_GET_ITEM(inargs, *pindex);
4011         ++*pindex;
4012         return Py_NewRef(v);
4013     }
4014     if (kwds && name) {
4015         if (PyDict_GetItemRef(kwds, name, &v) < 0) {
4016             return NULL;
4017         }
4018         if (v) {
4019             ++*pindex;
4020             return v;
4021         }
4022     }
4023     if (defval) {
4024         return Py_NewRef(defval);
4025     }
4026     /* we can't currently emit a better error message */
4027     if (name)
4028         PyErr_Format(PyExc_TypeError,
4029                      "required argument '%S' missing", name);
4030     else
4031         PyErr_Format(PyExc_TypeError,
4032                      "not enough arguments");
4033     return NULL;
4034 }
4035 
4036 /*
4037  This function implements higher level functionality plus the ability to call
4038  functions with keyword arguments by looking at parameter flags.  parameter
4039  flags is a tuple of 1, 2 or 3-tuples.  The first entry in each is an integer
4040  specifying the direction of the data transfer for this parameter - 'in',
4041  'out' or 'inout' (zero means the same as 'in').  The second entry is the
4042  parameter name, and the third is the default value if the parameter is
4043  missing in the function call.
4044 
4045  This function builds and returns a new tuple 'callargs' which contains the
4046  parameters to use in the call.  Items on this tuple are copied from the
4047  'inargs' tuple for 'in' and 'in, out' parameters, and constructed from the
4048  'argtypes' tuple for 'out' parameters.  It also calculates numretvals which
4049  is the number of return values for the function, outmask/inoutmask are
4050  bitmasks containing indexes into the callargs tuple specifying which
4051  parameters have to be returned.  _build_result builds the return value of the
4052  function.
4053 */
4054 static PyObject *
_build_callargs(ctypes_state * st,PyCFuncPtrObject * self,PyObject * argtypes,PyObject * inargs,PyObject * kwds,int * poutmask,int * pinoutmask,unsigned int * pnumretvals)4055 _build_callargs(ctypes_state *st, PyCFuncPtrObject *self, PyObject *argtypes,
4056                 PyObject *inargs, PyObject *kwds,
4057                 int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
4058 {
4059     PyObject *paramflags = self->paramflags;
4060     PyObject *callargs;
4061     Py_ssize_t i, len;
4062     int inargs_index = 0;
4063     /* It's a little bit difficult to determine how many arguments the
4064     function call requires/accepts.  For simplicity, we count the consumed
4065     args and compare this to the number of supplied args. */
4066     Py_ssize_t actual_args;
4067 
4068     *poutmask = 0;
4069     *pinoutmask = 0;
4070     *pnumretvals = 0;
4071 
4072     /* Trivial cases, where we either return inargs itself, or a slice of it. */
4073     if (argtypes == NULL || paramflags == NULL || PyTuple_GET_SIZE(argtypes) == 0) {
4074 #ifdef MS_WIN32
4075         if (self->index)
4076             return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs));
4077 #endif
4078         return Py_NewRef(inargs);
4079     }
4080 
4081     len = PyTuple_GET_SIZE(argtypes);
4082     callargs = PyTuple_New(len); /* the argument tuple we build */
4083     if (callargs == NULL)
4084         return NULL;
4085 
4086 #ifdef MS_WIN32
4087     /* For a COM method, skip the first arg */
4088     if (self->index) {
4089         inargs_index = 1;
4090     }
4091 #endif
4092     for (i = 0; i < len; ++i) {
4093         PyObject *item = PyTuple_GET_ITEM(paramflags, i);
4094         PyObject *ob;
4095         unsigned int flag;
4096         PyObject *name = NULL;
4097         PyObject *defval = NULL;
4098 
4099         /* This way seems to be ~2 us faster than the PyArg_ParseTuple
4100            calls below. */
4101         /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
4102         Py_ssize_t tsize = PyTuple_GET_SIZE(item);
4103         flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0));
4104         name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
4105         defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
4106 
4107         switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
4108         case PARAMFLAG_FIN | PARAMFLAG_FLCID:
4109             /* ['in', 'lcid'] parameter.  Always taken from defval,
4110              if given, else the integer 0. */
4111             if (defval == NULL) {
4112                 defval = _PyLong_GetZero();
4113             }
4114             Py_INCREF(defval);
4115             PyTuple_SET_ITEM(callargs, i, defval);
4116             break;
4117         case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
4118             *pinoutmask |= (1 << i); /* mark as inout arg */
4119             (*pnumretvals)++;
4120             /* fall through */
4121         case 0:
4122         case PARAMFLAG_FIN:
4123             /* 'in' parameter.  Copy it from inargs. */
4124             ob =_get_arg(&inargs_index, name, defval, inargs, kwds);
4125             if (ob == NULL)
4126                 goto error;
4127             PyTuple_SET_ITEM(callargs, i, ob);
4128             break;
4129         case PARAMFLAG_FOUT:
4130             /* XXX Refactor this code into a separate function. */
4131             /* 'out' parameter.
4132                argtypes[i] must be a POINTER to a c type.
4133 
4134                Cannot by supplied in inargs, but a defval will be used
4135                if available.  XXX Should we support getting it from kwds?
4136             */
4137             if (defval) {
4138                 /* XXX Using mutable objects as defval will
4139                    make the function non-threadsafe, unless we
4140                    copy the object in each invocation */
4141                 Py_INCREF(defval);
4142                 PyTuple_SET_ITEM(callargs, i, defval);
4143                 *poutmask |= (1 << i); /* mark as out arg */
4144                 (*pnumretvals)++;
4145                 break;
4146             }
4147             ob = PyTuple_GET_ITEM(argtypes, i);
4148             StgInfo *info;
4149             if (PyStgInfo_FromType(st, ob, &info) < 0) {
4150                 goto error;
4151             }
4152             if (info == NULL) {
4153                 /* Cannot happen: _validate_paramflags()
4154                   would not accept such an object */
4155                 PyErr_Format(PyExc_RuntimeError,
4156                              "NULL stginfo unexpected");
4157                 goto error;
4158             }
4159             if (PyUnicode_Check(info->proto)) {
4160                 PyErr_Format(
4161                     PyExc_TypeError,
4162                     "%s 'out' parameter must be passed as default value",
4163                     ((PyTypeObject *)ob)->tp_name);
4164                 goto error;
4165             }
4166             if (PyCArrayTypeObject_Check(st, ob)) {
4167                 ob = _PyObject_CallNoArgs(ob);
4168             }
4169             else {
4170                 /* Create an instance of the pointed-to type */
4171                 ob = _PyObject_CallNoArgs(info->proto);
4172             }
4173             /*
4174                XXX Is the following correct any longer?
4175                We must not pass a byref() to the array then but
4176                the array instance itself. Then, we cannot retrieve
4177                the result from the PyCArgObject.
4178             */
4179             if (ob == NULL)
4180                 goto error;
4181             /* The .from_param call that will occur later will pass this
4182                as a byref parameter. */
4183             PyTuple_SET_ITEM(callargs, i, ob);
4184             *poutmask |= (1 << i); /* mark as out arg */
4185             (*pnumretvals)++;
4186             break;
4187         default:
4188             PyErr_Format(PyExc_ValueError,
4189                          "paramflag %u not yet implemented", flag);
4190             goto error;
4191             break;
4192         }
4193     }
4194 
4195     /* We have counted the arguments we have consumed in 'inargs_index'.  This
4196        must be the same as len(inargs) + len(kwds), otherwise we have
4197        either too much or not enough arguments. */
4198 
4199     actual_args = PyTuple_GET_SIZE(inargs) + (kwds ? PyDict_GET_SIZE(kwds) : 0);
4200     if (actual_args != inargs_index) {
4201         /* When we have default values or named parameters, this error
4202            message is misleading.  See unittests/test_paramflags.py
4203          */
4204         PyErr_Format(PyExc_TypeError,
4205                      "call takes exactly %d arguments (%zd given)",
4206                      inargs_index, actual_args);
4207         goto error;
4208     }
4209 
4210     /* outmask is a bitmask containing indexes into callargs.  Items at
4211        these indexes contain values to return.
4212      */
4213     return callargs;
4214   error:
4215     Py_DECREF(callargs);
4216     return NULL;
4217 }
4218 
4219 /* See also:
4220    http://msdn.microsoft.com/library/en-us/com/html/769127a1-1a14-4ed4-9d38-7cf3e571b661.asp
4221 */
4222 /*
4223   Build return value of a function.
4224 
4225   Consumes the refcount on result and callargs.
4226 */
4227 static PyObject *
_build_result(PyObject * result,PyObject * callargs,int outmask,int inoutmask,unsigned int numretvals)4228 _build_result(PyObject *result, PyObject *callargs,
4229               int outmask, int inoutmask, unsigned int numretvals)
4230 {
4231     unsigned int i, index;
4232     int bit;
4233     PyObject *tup = NULL;
4234 
4235     if (callargs == NULL)
4236         return result;
4237     if (result == NULL || numretvals == 0) {
4238         Py_DECREF(callargs);
4239         return result;
4240     }
4241     Py_DECREF(result);
4242 
4243     /* tup will not be allocated if numretvals == 1 */
4244     /* allocate tuple to hold the result */
4245     if (numretvals > 1) {
4246         tup = PyTuple_New(numretvals);
4247         if (tup == NULL) {
4248             Py_DECREF(callargs);
4249             return NULL;
4250         }
4251     }
4252 
4253     index = 0;
4254     for (bit = 1, i = 0; i < 32; ++i, bit <<= 1) {
4255         PyObject *v;
4256         if (bit & inoutmask) {
4257             v = PyTuple_GET_ITEM(callargs, i);
4258             Py_INCREF(v);
4259             if (numretvals == 1) {
4260                 Py_DECREF(callargs);
4261                 return v;
4262             }
4263             PyTuple_SET_ITEM(tup, index, v);
4264             index++;
4265         } else if (bit & outmask) {
4266 
4267             v = PyTuple_GET_ITEM(callargs, i);
4268             v = PyObject_CallMethodNoArgs(v, &_Py_ID(__ctypes_from_outparam__));
4269             if (v == NULL || numretvals == 1) {
4270                 Py_DECREF(callargs);
4271                 return v;
4272             }
4273             PyTuple_SET_ITEM(tup, index, v);
4274             index++;
4275         }
4276         if (index == numretvals)
4277             break;
4278     }
4279 
4280     Py_DECREF(callargs);
4281     return tup;
4282 }
4283 
4284 static PyObject *
PyCFuncPtr_call(PyCFuncPtrObject * self,PyObject * inargs,PyObject * kwds)4285 PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
4286 {
4287     PyObject *restype;
4288     PyObject *converters;
4289     PyObject *checker;
4290     PyObject *argtypes;
4291     PyObject *result;
4292     PyObject *callargs;
4293     PyObject *errcheck;
4294 #ifdef MS_WIN32
4295     IUnknown *piunk = NULL;
4296 #endif
4297     void *pProc = NULL;
4298 
4299     int inoutmask;
4300     int outmask;
4301     unsigned int numretvals;
4302 
4303     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
4304     StgInfo *info;
4305     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
4306         return NULL;
4307     }
4308     assert(info); /* Cannot be NULL for PyCFuncPtrObject instances */
4309 
4310     restype = self->restype ? self->restype : info->restype;
4311     converters = self->converters ? self->converters : info->converters;
4312     checker = self->checker ? self->checker : info->checker;
4313     argtypes = self->argtypes ? self->argtypes : info->argtypes;
4314 /* later, we probably want to have an errcheck field in stginfo */
4315     errcheck = self->errcheck /* ? self->errcheck : info->errcheck */;
4316 
4317 
4318     pProc = *(void **)self->b_ptr;
4319 #ifdef MS_WIN32
4320     if (self->index) {
4321         /* It's a COM method */
4322         CDataObject *this;
4323         this = (CDataObject *)PyTuple_GetItem(inargs, 0); /* borrowed ref! */
4324         if (!this) {
4325             PyErr_SetString(PyExc_ValueError,
4326                             "native com method call without 'this' parameter");
4327             return NULL;
4328         }
4329         if (!CDataObject_Check(st, this)) {
4330             PyErr_SetString(PyExc_TypeError,
4331                             "Expected a COM this pointer as first argument");
4332             return NULL;
4333         }
4334         /* there should be more checks? No, in Python */
4335         /* First arg is a pointer to an interface instance */
4336         if (!this->b_ptr || *(void **)this->b_ptr == NULL) {
4337             PyErr_SetString(PyExc_ValueError,
4338                             "NULL COM pointer access");
4339             return NULL;
4340         }
4341         piunk = *(IUnknown **)this->b_ptr;
4342         if (NULL == piunk->lpVtbl) {
4343             PyErr_SetString(PyExc_ValueError,
4344                             "COM method call without VTable");
4345             return NULL;
4346         }
4347         pProc = ((void **)piunk->lpVtbl)[self->index - 0x1000];
4348     }
4349 #endif
4350     callargs = _build_callargs(st, self, argtypes,
4351                                inargs, kwds,
4352                                &outmask, &inoutmask, &numretvals);
4353     if (callargs == NULL)
4354         return NULL;
4355 
4356     if (converters) {
4357         int required = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(converters),
4358                                         Py_ssize_t, int);
4359         int actual = Py_SAFE_DOWNCAST(PyTuple_GET_SIZE(callargs),
4360                                       Py_ssize_t, int);
4361 
4362         if ((info->flags & FUNCFLAG_CDECL) == FUNCFLAG_CDECL) {
4363             /* For cdecl functions, we allow more actual arguments
4364                than the length of the argtypes tuple.
4365             */
4366             if (required > actual) {
4367                 Py_DECREF(callargs);
4368                 PyErr_Format(PyExc_TypeError,
4369               "this function takes at least %d argument%s (%d given)",
4370                                  required,
4371                                  required == 1 ? "" : "s",
4372                                  actual);
4373                 return NULL;
4374             }
4375         } else if (required != actual) {
4376             Py_DECREF(callargs);
4377             PyErr_Format(PyExc_TypeError,
4378                  "this function takes %d argument%s (%d given)",
4379                      required,
4380                      required == 1 ? "" : "s",
4381                      actual);
4382             return NULL;
4383         }
4384     }
4385 
4386     result = _ctypes_callproc(st,
4387                        pProc,
4388                        callargs,
4389 #ifdef MS_WIN32
4390                        piunk,
4391                        self->iid,
4392 #endif
4393                        info->flags,
4394                        converters,
4395                        restype,
4396                        checker);
4397 /* The 'errcheck' protocol */
4398     if (result != NULL && errcheck) {
4399         PyObject *v = PyObject_CallFunctionObjArgs(errcheck,
4400                                                    result,
4401                                                    self,
4402                                                    callargs,
4403                                                    NULL);
4404         /* If the errcheck function failed, return NULL.
4405            If the errcheck function returned callargs unchanged,
4406            continue normal processing.
4407            If the errcheck function returned something else,
4408            use that as result.
4409         */
4410         if (v == NULL || v != callargs) {
4411             Py_DECREF(result);
4412             Py_DECREF(callargs);
4413             return v;
4414         }
4415         Py_DECREF(v);
4416     }
4417 
4418     return _build_result(result, callargs,
4419                          outmask, inoutmask, numretvals);
4420 }
4421 
4422 static int
PyCFuncPtr_traverse(PyCFuncPtrObject * self,visitproc visit,void * arg)4423 PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
4424 {
4425     Py_VISIT(self->callable);
4426     Py_VISIT(self->restype);
4427     Py_VISIT(self->checker);
4428     Py_VISIT(self->errcheck);
4429     Py_VISIT(self->argtypes);
4430     Py_VISIT(self->converters);
4431     Py_VISIT(self->paramflags);
4432     Py_VISIT(self->thunk);
4433     return PyCData_traverse((CDataObject *)self, visit, arg);
4434 }
4435 
4436 static int
PyCFuncPtr_clear(PyCFuncPtrObject * self)4437 PyCFuncPtr_clear(PyCFuncPtrObject *self)
4438 {
4439     Py_CLEAR(self->callable);
4440     Py_CLEAR(self->restype);
4441     Py_CLEAR(self->checker);
4442     Py_CLEAR(self->errcheck);
4443     Py_CLEAR(self->argtypes);
4444     Py_CLEAR(self->converters);
4445     Py_CLEAR(self->paramflags);
4446     Py_CLEAR(self->thunk);
4447     return PyCData_clear((CDataObject *)self);
4448 }
4449 
4450 static void
PyCFuncPtr_dealloc(PyCFuncPtrObject * self)4451 PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
4452 {
4453     PyObject_GC_UnTrack(self);
4454     PyCFuncPtr_clear(self);
4455     PyTypeObject *type = Py_TYPE(self);
4456     type->tp_free((PyObject *)self);
4457     Py_DECREF(type);
4458 }
4459 
4460 static PyObject *
PyCFuncPtr_repr(PyCFuncPtrObject * self)4461 PyCFuncPtr_repr(PyCFuncPtrObject *self)
4462 {
4463 #ifdef MS_WIN32
4464     if (self->index)
4465         return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
4466                                    self->index - 0x1000,
4467                                    Py_TYPE(self)->tp_name,
4468                                    self);
4469 #endif
4470     return PyUnicode_FromFormat("<%s object at %p>",
4471                                Py_TYPE(self)->tp_name,
4472                                self);
4473 }
4474 
4475 static int
PyCFuncPtr_bool(PyCFuncPtrObject * self)4476 PyCFuncPtr_bool(PyCFuncPtrObject *self)
4477 {
4478     return ((*(void **)self->b_ptr != NULL)
4479 #ifdef MS_WIN32
4480         || (self->index != 0)
4481 #endif
4482         );
4483 }
4484 
4485 static PyType_Slot pycfuncptr_slots[] = {
4486     {Py_tp_dealloc, PyCFuncPtr_dealloc},
4487     {Py_tp_repr, PyCFuncPtr_repr},
4488     {Py_tp_call, PyCFuncPtr_call},
4489     {Py_tp_doc, PyDoc_STR("Function Pointer")},
4490     {Py_tp_traverse, PyCFuncPtr_traverse},
4491     {Py_tp_clear, PyCFuncPtr_clear},
4492     {Py_tp_getset, PyCFuncPtr_getsets},
4493     {Py_tp_new, PyCFuncPtr_new},
4494     {Py_bf_getbuffer, PyCData_NewGetBuffer},
4495     {Py_nb_bool, PyCFuncPtr_bool},
4496     {0, NULL},
4497 };
4498 
4499 static PyType_Spec pycfuncptr_spec = {
4500     .name = "_ctypes.CFuncPtr",
4501     .basicsize = sizeof(PyCFuncPtrObject),
4502     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
4503               Py_TPFLAGS_IMMUTABLETYPE),
4504     .slots = pycfuncptr_slots,
4505 };
4506 
4507 /*****************************************************************/
4508 /*
4509   Struct_Type
4510 */
4511 /*
4512   This function is called to initialize a Structure or Union with positional
4513   arguments. It calls itself recursively for all Structure or Union base
4514   classes, then retrieves the _fields_ member to associate the argument
4515   position with the correct field name.
4516 
4517   Returns -1 on error, or the index of next argument on success.
4518  */
4519 static Py_ssize_t
_init_pos_args(PyObject * self,PyTypeObject * type,PyObject * args,PyObject * kwds,Py_ssize_t index)4520 _init_pos_args(PyObject *self, PyTypeObject *type,
4521                PyObject *args, PyObject *kwds,
4522                Py_ssize_t index)
4523 {
4524     PyObject *fields;
4525     Py_ssize_t i;
4526 
4527     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
4528     StgInfo *baseinfo;
4529     if (PyStgInfo_FromType(st, (PyObject *)type->tp_base, &baseinfo) < 0) {
4530         return -1;
4531     }
4532     if (baseinfo) {
4533         index = _init_pos_args(self, type->tp_base,
4534                                args, kwds,
4535                                index);
4536         if (index == -1)
4537             return -1;
4538     }
4539 
4540     StgInfo *info;
4541     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
4542         return -1;
4543     }
4544     assert(info);
4545 
4546     PyObject *attrdict = PyType_GetDict(type);
4547     assert(attrdict);
4548 
4549     fields = PyDict_GetItemWithError((PyObject *)attrdict, &_Py_ID(_fields_));
4550     Py_CLEAR(attrdict);
4551     if (fields == NULL) {
4552         if (PyErr_Occurred()) {
4553             return -1;
4554         }
4555         return index;
4556     }
4557 
4558     for (i = index;
4559          i < info->length && i < PyTuple_GET_SIZE(args);
4560          ++i) {
4561         PyObject *pair = PySequence_GetItem(fields, i - index);
4562         PyObject *name, *val;
4563         int res;
4564         if (!pair)
4565             return -1;
4566         name = PySequence_GetItem(pair, 0);
4567         if (!name) {
4568             Py_DECREF(pair);
4569             return -1;
4570         }
4571         val = PyTuple_GET_ITEM(args, i);
4572         if (kwds) {
4573             res = PyDict_Contains(kwds, name);
4574             if (res != 0) {
4575                 if (res > 0) {
4576                     PyErr_Format(PyExc_TypeError,
4577                                  "duplicate values for field %R",
4578                                  name);
4579                 }
4580                 Py_DECREF(pair);
4581                 Py_DECREF(name);
4582                 return -1;
4583             }
4584         }
4585 
4586         res = PyObject_SetAttr(self, name, val);
4587         Py_DECREF(pair);
4588         Py_DECREF(name);
4589         if (res == -1)
4590             return -1;
4591     }
4592     return info->length;
4593 }
4594 
4595 static int
Struct_init(PyObject * self,PyObject * args,PyObject * kwds)4596 Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
4597 {
4598 /* Optimization possible: Store the attribute names _fields_[x][0]
4599  * in C accessible fields somewhere ?
4600  */
4601     if (!PyTuple_Check(args)) {
4602         PyErr_SetString(PyExc_TypeError,
4603                         "args not a tuple?");
4604         return -1;
4605     }
4606     if (PyTuple_GET_SIZE(args)) {
4607         Py_ssize_t res = _init_pos_args(self, Py_TYPE(self),
4608                                         args, kwds, 0);
4609         if (res == -1)
4610             return -1;
4611         if (res < PyTuple_GET_SIZE(args)) {
4612             PyErr_SetString(PyExc_TypeError,
4613                             "too many initializers");
4614             return -1;
4615         }
4616     }
4617 
4618     if (kwds) {
4619         PyObject *key, *value;
4620         Py_ssize_t pos = 0;
4621         while(PyDict_Next(kwds, &pos, &key, &value)) {
4622             if (-1 == PyObject_SetAttr(self, key, value))
4623                 return -1;
4624         }
4625     }
4626     return 0;
4627 }
4628 
4629 static PyType_Slot pycstruct_slots[] = {
4630     {Py_tp_doc, PyDoc_STR("Structure base class")},
4631     {Py_tp_init, Struct_init},
4632     {Py_tp_new, GenericPyCData_new},
4633     {Py_bf_getbuffer, PyCData_NewGetBuffer},
4634     {0, NULL},
4635 };
4636 
4637 static PyType_Spec pycstruct_spec = {
4638     .name = "_ctypes.Structure",
4639     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
4640               Py_TPFLAGS_IMMUTABLETYPE),
4641     .slots = pycstruct_slots,
4642 };
4643 
4644 static PyType_Slot pycunion_slots[] = {
4645     {Py_tp_doc, PyDoc_STR("Union base class")},
4646     {Py_tp_init, Struct_init},
4647     {Py_tp_new, GenericPyCData_new},
4648     {Py_bf_getbuffer, PyCData_NewGetBuffer},
4649     {0, NULL},
4650 };
4651 
4652 static PyType_Spec pycunion_spec = {
4653     .name = "_ctypes.Union",
4654     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
4655               Py_TPFLAGS_IMMUTABLETYPE),
4656     .slots = pycunion_slots,
4657 };
4658 
4659 
4660 /******************************************************************/
4661 /*
4662   PyCArray_Type
4663 */
4664 static int
Array_init(CDataObject * self,PyObject * args,PyObject * kw)4665 Array_init(CDataObject *self, PyObject *args, PyObject *kw)
4666 {
4667     Py_ssize_t i;
4668     Py_ssize_t n;
4669 
4670     if (!PyTuple_Check(args)) {
4671         PyErr_SetString(PyExc_TypeError,
4672                         "args not a tuple?");
4673         return -1;
4674     }
4675     n = PyTuple_GET_SIZE(args);
4676     for (i = 0; i < n; ++i) {
4677         PyObject *v;
4678         v = PyTuple_GET_ITEM(args, i);
4679         if (-1 == PySequence_SetItem((PyObject *)self, i, v))
4680             return -1;
4681     }
4682     return 0;
4683 }
4684 
4685 static PyObject *
Array_item(PyObject * myself,Py_ssize_t index)4686 Array_item(PyObject *myself, Py_ssize_t index)
4687 {
4688     CDataObject *self = (CDataObject *)myself;
4689     Py_ssize_t offset, size;
4690 
4691     if (index < 0 || index >= self->b_length) {
4692         PyErr_SetString(PyExc_IndexError,
4693                         "invalid index");
4694         return NULL;
4695     }
4696 
4697     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
4698     StgInfo *stginfo;
4699     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
4700         return NULL;
4701     }
4702 
4703     /* Would it be clearer if we got the item size from
4704        stginfo->proto's stginfo?
4705     */
4706     size = stginfo->size / stginfo->length;
4707     offset = index * size;
4708 
4709     return PyCData_get(st, stginfo->proto, stginfo->getfunc, (PyObject *)self,
4710                      index, size, self->b_ptr + offset);
4711 }
4712 
4713 static PyObject *
Array_subscript(PyObject * myself,PyObject * item)4714 Array_subscript(PyObject *myself, PyObject *item)
4715 {
4716     CDataObject *self = (CDataObject *)myself;
4717 
4718     if (PyIndex_Check(item)) {
4719         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4720 
4721         if (i == -1 && PyErr_Occurred())
4722             return NULL;
4723         if (i < 0)
4724             i += self->b_length;
4725         return Array_item(myself, i);
4726     }
4727     else if (PySlice_Check(item)) {
4728         PyObject *proto;
4729         PyObject *np;
4730         Py_ssize_t start, stop, step, slicelen, i;
4731         size_t cur;
4732 
4733         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4734             return NULL;
4735         }
4736         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4737 
4738         ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
4739         StgInfo *stginfo;
4740         if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
4741             return NULL;
4742         }
4743         assert(stginfo); /* Cannot be NULL for array object instances */
4744         proto = stginfo->proto;
4745         StgInfo *iteminfo;
4746         if (PyStgInfo_FromType(st, proto, &iteminfo) < 0) {
4747             return NULL;
4748         }
4749         assert(iteminfo); /* proto is the item type of the array, a
4750                              ctypes type, so this cannot be NULL */
4751 
4752         if (iteminfo->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
4753             char *ptr = (char *)self->b_ptr;
4754             char *dest;
4755 
4756             if (slicelen <= 0)
4757                 return PyBytes_FromStringAndSize("", 0);
4758             if (step == 1) {
4759                 return PyBytes_FromStringAndSize(ptr + start,
4760                                                  slicelen);
4761             }
4762             dest = (char *)PyMem_Malloc(slicelen);
4763 
4764             if (dest == NULL)
4765                 return PyErr_NoMemory();
4766 
4767             for (cur = start, i = 0; i < slicelen;
4768                  cur += step, i++) {
4769                 dest[i] = ptr[cur];
4770             }
4771 
4772             np = PyBytes_FromStringAndSize(dest, slicelen);
4773             PyMem_Free(dest);
4774             return np;
4775         }
4776         if (iteminfo->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
4777             wchar_t *ptr = (wchar_t *)self->b_ptr;
4778             wchar_t *dest;
4779 
4780             if (slicelen <= 0)
4781                 return PyUnicode_New(0, 0);
4782             if (step == 1) {
4783                 return PyUnicode_FromWideChar(ptr + start,
4784                                               slicelen);
4785             }
4786 
4787             dest = PyMem_New(wchar_t, slicelen);
4788             if (dest == NULL) {
4789                 PyErr_NoMemory();
4790                 return NULL;
4791             }
4792 
4793             for (cur = start, i = 0; i < slicelen;
4794                  cur += step, i++) {
4795                 dest[i] = ptr[cur];
4796             }
4797 
4798             np = PyUnicode_FromWideChar(dest, slicelen);
4799             PyMem_Free(dest);
4800             return np;
4801         }
4802 
4803         np = PyList_New(slicelen);
4804         if (np == NULL)
4805             return NULL;
4806 
4807         for (cur = start, i = 0; i < slicelen;
4808              cur += step, i++) {
4809             PyObject *v = Array_item(myself, cur);
4810             if (v == NULL) {
4811                 Py_DECREF(np);
4812                 return NULL;
4813             }
4814             PyList_SET_ITEM(np, i, v);
4815         }
4816         return np;
4817     }
4818     else {
4819         PyErr_SetString(PyExc_TypeError,
4820                         "indices must be integers");
4821         return NULL;
4822     }
4823 
4824 }
4825 
4826 static int
Array_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)4827 Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
4828 {
4829     CDataObject *self = (CDataObject *)myself;
4830     Py_ssize_t size, offset;
4831     char *ptr;
4832 
4833     if (value == NULL) {
4834         PyErr_SetString(PyExc_TypeError,
4835                         "Array does not support item deletion");
4836         return -1;
4837     }
4838 
4839     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
4840     StgInfo *stginfo;
4841     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
4842         return -1;
4843     }
4844     assert(stginfo); /* Cannot be NULL for array object instances */
4845 
4846     if (index < 0 || index >= stginfo->length) {
4847         PyErr_SetString(PyExc_IndexError,
4848                         "invalid index");
4849         return -1;
4850     }
4851     size = stginfo->size / stginfo->length;
4852     offset = index * size;
4853     ptr = self->b_ptr + offset;
4854 
4855     return PyCData_set(st, (PyObject *)self, stginfo->proto, stginfo->setfunc, value,
4856                      index, size, ptr);
4857 }
4858 
4859 static int
Array_ass_subscript(PyObject * myself,PyObject * item,PyObject * value)4860 Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
4861 {
4862     CDataObject *self = (CDataObject *)myself;
4863 
4864     if (value == NULL) {
4865         PyErr_SetString(PyExc_TypeError,
4866                         "Array does not support item deletion");
4867         return -1;
4868     }
4869 
4870     if (PyIndex_Check(item)) {
4871         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
4872 
4873         if (i == -1 && PyErr_Occurred())
4874             return -1;
4875         if (i < 0)
4876             i += self->b_length;
4877         return Array_ass_item(myself, i, value);
4878     }
4879     else if (PySlice_Check(item)) {
4880         Py_ssize_t start, stop, step, slicelen, otherlen, i;
4881         size_t cur;
4882 
4883         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
4884             return -1;
4885         }
4886         slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step);
4887         if ((step < 0 && start < stop) ||
4888             (step > 0 && start > stop))
4889             stop = start;
4890 
4891         otherlen = PySequence_Length(value);
4892         if (otherlen != slicelen) {
4893             PyErr_SetString(PyExc_ValueError,
4894                 "Can only assign sequence of same size");
4895             return -1;
4896         }
4897         for (cur = start, i = 0; i < otherlen; cur += step, i++) {
4898             PyObject *item = PySequence_GetItem(value, i);
4899             int result;
4900             if (item == NULL)
4901                 return -1;
4902             result = Array_ass_item(myself, cur, item);
4903             Py_DECREF(item);
4904             if (result == -1)
4905                 return -1;
4906         }
4907         return 0;
4908     }
4909     else {
4910         PyErr_SetString(PyExc_TypeError,
4911                         "indices must be integer");
4912         return -1;
4913     }
4914 }
4915 
4916 static Py_ssize_t
Array_length(PyObject * myself)4917 Array_length(PyObject *myself)
4918 {
4919     CDataObject *self = (CDataObject *)myself;
4920     return self->b_length;
4921 }
4922 
4923 static PyMethodDef Array_methods[] = {
4924     {"__class_getitem__",    Py_GenericAlias,
4925     METH_O|METH_CLASS,       PyDoc_STR("See PEP 585")},
4926     { NULL, NULL }
4927 };
4928 
4929 PyDoc_STRVAR(array_doc,
4930 "Abstract base class for arrays.\n"
4931 "\n"
4932 "The recommended way to create concrete array types is by multiplying any\n"
4933 "ctypes data type with a non-negative integer. Alternatively, you can subclass\n"
4934 "this type and define _length_ and _type_ class variables. Array elements can\n"
4935 "be read and written using standard subscript and slice accesses for slice\n"
4936 "reads, the resulting object is not itself an Array."
4937 );
4938 
4939 static PyType_Slot pycarray_slots[] = {
4940     {Py_tp_doc, (char*)array_doc},
4941     {Py_tp_methods, Array_methods},
4942     {Py_tp_init, Array_init},
4943     {Py_tp_new, GenericPyCData_new},
4944     {Py_bf_getbuffer, PyCData_NewGetBuffer},
4945     {Py_sq_length, Array_length},
4946     {Py_sq_item, Array_item},
4947     {Py_sq_ass_item, Array_ass_item},
4948     {Py_mp_length, Array_length},
4949     {Py_mp_subscript, Array_subscript},
4950     {Py_mp_ass_subscript, Array_ass_subscript},
4951     {0, NULL},
4952 };
4953 
4954 static PyType_Spec pycarray_spec = {
4955     .name = "_ctypes.Array",
4956     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
4957               Py_TPFLAGS_IMMUTABLETYPE),
4958     .slots = pycarray_slots,
4959 };
4960 
4961 PyObject *
PyCArrayType_from_ctype(ctypes_state * st,PyObject * itemtype,Py_ssize_t length)4962 PyCArrayType_from_ctype(ctypes_state *st, PyObject *itemtype, Py_ssize_t length)
4963 {
4964     PyObject *key;
4965     char name[256];
4966     PyObject *len;
4967 
4968     if (st->array_cache == NULL) {
4969         st->array_cache = PyDict_New();
4970         if (st->array_cache == NULL) {
4971             return NULL;
4972         }
4973     }
4974     len = PyLong_FromSsize_t(length);
4975     if (len == NULL)
4976         return NULL;
4977     key = PyTuple_Pack(2, itemtype, len);
4978     Py_DECREF(len);
4979     if (!key)
4980         return NULL;
4981 
4982     PyObject *result;
4983     if (_PyDict_GetItemProxy(st->array_cache, key, &result) != 0) {
4984         // found or error
4985         Py_DECREF(key);
4986         return result;
4987     }
4988     // not found
4989     if (!PyType_Check(itemtype)) {
4990         PyErr_SetString(PyExc_TypeError,
4991                         "Expected a type object");
4992         Py_DECREF(key);
4993         return NULL;
4994     }
4995 #ifdef MS_WIN64
4996     sprintf(name, "%.200s_Array_%Id",
4997         ((PyTypeObject *)itemtype)->tp_name, length);
4998 #else
4999     sprintf(name, "%.200s_Array_%ld",
5000         ((PyTypeObject *)itemtype)->tp_name, (long)length);
5001 #endif
5002     result = PyObject_CallFunction((PyObject *)st->PyCArrayType_Type,
5003                                    "s(O){s:n,s:O}",
5004                                    name,
5005                                    st->PyCArray_Type,
5006                                    "_length_",
5007                                    length,
5008                                    "_type_",
5009                                    itemtype
5010         );
5011     if (result == NULL) {
5012         Py_DECREF(key);
5013         return NULL;
5014     }
5015     if (PyDict_SetItemProxy(st, st->array_cache, key, result) < 0) {
5016         Py_DECREF(key);
5017         Py_DECREF(result);
5018         return NULL;
5019     }
5020     Py_DECREF(key);
5021     return result;
5022 }
5023 
5024 
5025 /******************************************************************/
5026 /*
5027   Simple_Type
5028 */
5029 
5030 /*[clinic input]
5031 class _ctypes.Simple "PyObject *" "clinic_state()->Simple_Type"
5032 [clinic start generated code]*/
5033 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=016c476c7aa8b8a8]*/
5034 
5035 
5036 static int
Simple_set_value(CDataObject * self,PyObject * value,void * Py_UNUSED (ignored))5037 Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
5038 {
5039     PyObject *result;
5040 
5041     if (value == NULL) {
5042         PyErr_SetString(PyExc_TypeError,
5043                         "can't delete attribute");
5044         return -1;
5045     }
5046 
5047     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
5048     StgInfo *info;
5049     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
5050         return -1;
5051     }
5052     assert(info); /* Cannot be NULL for CDataObject instances */
5053     assert(info->setfunc);
5054 
5055     result = info->setfunc(self->b_ptr, value, info->size);
5056     if (!result)
5057         return -1;
5058 
5059     /* consumes the refcount the setfunc returns */
5060     return KeepRef(self, 0, result);
5061 }
5062 
5063 static int
Simple_init(CDataObject * self,PyObject * args,PyObject * kw)5064 Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
5065 {
5066     PyObject *value = NULL;
5067     if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
5068         return -1;
5069     if (value)
5070         return Simple_set_value(self, value, NULL);
5071     return 0;
5072 }
5073 
5074 static PyObject *
Simple_get_value(CDataObject * self,void * Py_UNUSED (ignored))5075 Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
5076 {
5077     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
5078     StgInfo *info;
5079     if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
5080         return NULL;
5081     }
5082     assert(info); /* Cannot be NULL for CDataObject instances */
5083     assert(info->getfunc);
5084     return info->getfunc(self->b_ptr, self->b_size);
5085 }
5086 
5087 static PyGetSetDef Simple_getsets[] = {
5088     { "value", (getter)Simple_get_value, (setter)Simple_set_value,
5089       "current value", NULL },
5090     { NULL, NULL }
5091 };
5092 
5093 /*[clinic input]
5094 _ctypes.Simple.__ctypes_from_outparam__ as Simple_from_outparm
5095 
5096     self: self
5097     cls: defining_class
5098     /
5099 [clinic start generated code]*/
5100 
5101 static PyObject *
Simple_from_outparm_impl(PyObject * self,PyTypeObject * cls)5102 Simple_from_outparm_impl(PyObject *self, PyTypeObject *cls)
5103 /*[clinic end generated code: output=6c61d90da8aa9b4f input=0f362803fb4629d5]*/
5104 {
5105     ctypes_state *st = get_module_state_by_class(cls);
5106     if (_ctypes_simple_instance(st, (PyObject *)Py_TYPE(self))) {
5107         return Py_NewRef(self);
5108     }
5109     /* call stginfo->getfunc */
5110     return Simple_get_value((CDataObject *)self, NULL);
5111 }
5112 
5113 static PyMethodDef Simple_methods[] = {
5114     SIMPLE_FROM_OUTPARM_METHODDEF
5115     { NULL, NULL },
5116 };
5117 
Simple_bool(CDataObject * self)5118 static int Simple_bool(CDataObject *self)
5119 {
5120     return memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
5121 }
5122 
5123 /* "%s(%s)" % (self.__class__.__name__, self.value) */
5124 static PyObject *
Simple_repr(CDataObject * self)5125 Simple_repr(CDataObject *self)
5126 {
5127     PyObject *val, *result;
5128     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
5129 
5130     if (Py_TYPE(self)->tp_base != st->Simple_Type) {
5131         return PyUnicode_FromFormat("<%s object at %p>",
5132                                    Py_TYPE(self)->tp_name, self);
5133     }
5134 
5135     val = Simple_get_value(self, NULL);
5136     if (val == NULL)
5137         return NULL;
5138 
5139     result = PyUnicode_FromFormat("%s(%R)",
5140                                   Py_TYPE(self)->tp_name, val);
5141     Py_DECREF(val);
5142     return result;
5143 }
5144 
5145 static PyType_Slot pycsimple_slots[] = {
5146     {Py_tp_repr, &Simple_repr},
5147     {Py_tp_doc, PyDoc_STR("XXX to be provided")},
5148     {Py_tp_methods, Simple_methods},
5149     {Py_tp_getset, Simple_getsets},
5150     {Py_tp_init, Simple_init},
5151     {Py_tp_new, GenericPyCData_new},
5152     {Py_bf_getbuffer, PyCData_NewGetBuffer},
5153     {Py_nb_bool, Simple_bool},
5154     {0, NULL},
5155 };
5156 
5157 static PyType_Spec pycsimple_spec = {
5158     .name = "_ctypes._SimpleCData",
5159     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
5160               Py_TPFLAGS_IMMUTABLETYPE),
5161     .slots = pycsimple_slots,
5162 };
5163 
5164 
5165 /******************************************************************/
5166 /*
5167   PyCPointer_Type
5168 */
5169 static PyObject *
Pointer_item(PyObject * myself,Py_ssize_t index)5170 Pointer_item(PyObject *myself, Py_ssize_t index)
5171 {
5172     CDataObject *self = (CDataObject *)myself;
5173     Py_ssize_t size;
5174     Py_ssize_t offset;
5175     PyObject *proto;
5176 
5177     if (*(void **)self->b_ptr == NULL) {
5178         PyErr_SetString(PyExc_ValueError,
5179                         "NULL pointer access");
5180         return NULL;
5181     }
5182 
5183     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
5184     StgInfo *stginfo;
5185     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
5186         return NULL;
5187     }
5188     assert(stginfo); /* Cannot be NULL for pointer object instances */
5189 
5190     proto = stginfo->proto;
5191     assert(proto);
5192 
5193     StgInfo *iteminfo;
5194     if (PyStgInfo_FromType(st, proto, &iteminfo) < 0) {
5195         return NULL;
5196     }
5197     assert(iteminfo); /* proto is the item type of the pointer, a ctypes
5198                          type, so this cannot be NULL */
5199 
5200     size = iteminfo->size;
5201     offset = index * iteminfo->size;
5202 
5203     return PyCData_get(st, proto, stginfo->getfunc, (PyObject *)self,
5204                      index, size, (*(char **)self->b_ptr) + offset);
5205 }
5206 
5207 static int
Pointer_ass_item(PyObject * myself,Py_ssize_t index,PyObject * value)5208 Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
5209 {
5210     CDataObject *self = (CDataObject *)myself;
5211     Py_ssize_t size;
5212     Py_ssize_t offset;
5213     PyObject *proto;
5214 
5215     if (value == NULL) {
5216         PyErr_SetString(PyExc_TypeError,
5217                         "Pointer does not support item deletion");
5218         return -1;
5219     }
5220 
5221     if (*(void **)self->b_ptr == NULL) {
5222         PyErr_SetString(PyExc_ValueError,
5223                         "NULL pointer access");
5224         return -1;
5225     }
5226 
5227     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
5228     StgInfo *stginfo;
5229     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
5230         return -1;
5231     }
5232     assert(stginfo); /* Cannot be NULL for pointer instances */
5233 
5234     proto = stginfo->proto;
5235     assert(proto);
5236 
5237     StgInfo *iteminfo;
5238     if (PyStgInfo_FromType(st, proto, &iteminfo) < 0) {
5239         return -1;
5240     }
5241     assert(iteminfo); /* Cannot be NULL because the itemtype of a pointer
5242                          is always a ctypes type */
5243 
5244     size = iteminfo->size;
5245     offset = index * iteminfo->size;
5246 
5247     return PyCData_set(st, (PyObject *)self, proto, stginfo->setfunc, value,
5248                      index, size, (*(char **)self->b_ptr) + offset);
5249 }
5250 
5251 static PyObject *
Pointer_get_contents(CDataObject * self,void * closure)5252 Pointer_get_contents(CDataObject *self, void *closure)
5253 {
5254     if (*(void **)self->b_ptr == NULL) {
5255         PyErr_SetString(PyExc_ValueError,
5256                         "NULL pointer access");
5257         return NULL;
5258     }
5259 
5260     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
5261     StgInfo *stginfo;
5262     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
5263         return NULL;
5264     }
5265     assert(stginfo); /* Cannot be NULL for pointer instances */
5266 
5267     return PyCData_FromBaseObj(st, stginfo->proto,
5268                              (PyObject *)self, 0,
5269                              *(void **)self->b_ptr);
5270 }
5271 
5272 static int
Pointer_set_contents(CDataObject * self,PyObject * value,void * closure)5273 Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
5274 {
5275     CDataObject *dst;
5276     PyObject *keep;
5277 
5278     if (value == NULL) {
5279         PyErr_SetString(PyExc_TypeError,
5280                         "Pointer does not support item deletion");
5281         return -1;
5282     }
5283     ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
5284     StgInfo *stginfo;
5285     if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
5286         return -1;
5287     }
5288     assert(stginfo); /* Cannot be NULL for pointer instances */
5289     assert(stginfo->proto);
5290     if (!CDataObject_Check(st, value)) {
5291         int res = PyObject_IsInstance(value, stginfo->proto);
5292         if (res == -1)
5293             return -1;
5294         if (!res) {
5295             PyErr_Format(PyExc_TypeError,
5296                          "expected %s instead of %s",
5297                          ((PyTypeObject *)(stginfo->proto))->tp_name,
5298                          Py_TYPE(value)->tp_name);
5299             return -1;
5300         }
5301     }
5302 
5303     dst = (CDataObject *)value;
5304     *(void **)self->b_ptr = dst->b_ptr;
5305 
5306     /*
5307        A Pointer instance must keep the value it points to alive.  So, a
5308        pointer instance has b_length set to 2 instead of 1, and we set
5309        'value' itself as the second item of the b_objects list, additionally.
5310     */
5311     Py_INCREF(value);
5312     if (-1 == KeepRef(self, 1, value))
5313         return -1;
5314 
5315     keep = GetKeepedObjects(dst);
5316     if (keep == NULL)
5317         return -1;
5318 
5319     Py_INCREF(keep);
5320     return KeepRef(self, 0, keep);
5321 }
5322 
5323 static PyGetSetDef Pointer_getsets[] = {
5324     { "contents", (getter)Pointer_get_contents,
5325       (setter)Pointer_set_contents,
5326       "the object this pointer points to (read-write)", NULL },
5327     { NULL, NULL }
5328 };
5329 
5330 static int
Pointer_init(CDataObject * self,PyObject * args,PyObject * kw)5331 Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
5332 {
5333     PyObject *value = NULL;
5334 
5335     if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
5336         return -1;
5337     if (value == NULL)
5338         return 0;
5339     return Pointer_set_contents(self, value, NULL);
5340 }
5341 
5342 static PyObject *
Pointer_new(PyTypeObject * type,PyObject * args,PyObject * kw)5343 Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
5344 {
5345     ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
5346     StgInfo *info;
5347     if (PyStgInfo_FromType(st, (PyObject *)type, &info) < 0) {
5348         return NULL;
5349     }
5350     if (!info || !info->proto) {
5351         PyErr_SetString(PyExc_TypeError,
5352                         "Cannot create instance: has no _type_");
5353         return NULL;
5354     }
5355     return generic_pycdata_new(st, type, args, kw);
5356 }
5357 
5358 static PyObject *
Pointer_subscript(PyObject * myself,PyObject * item)5359 Pointer_subscript(PyObject *myself, PyObject *item)
5360 {
5361     CDataObject *self = (CDataObject *)myself;
5362     if (PyIndex_Check(item)) {
5363         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
5364         if (i == -1 && PyErr_Occurred())
5365             return NULL;
5366         return Pointer_item(myself, i);
5367     }
5368     else if (PySlice_Check(item)) {
5369         PySliceObject *slice = (PySliceObject *)item;
5370         Py_ssize_t start, stop, step;
5371         PyObject *np;
5372         PyObject *proto;
5373         Py_ssize_t i, len;
5374         size_t cur;
5375 
5376         /* Since pointers have no length, and we want to apply
5377            different semantics to negative indices than normal
5378            slicing, we have to dissect the slice object ourselves.*/
5379         if (slice->step == Py_None) {
5380             step = 1;
5381         }
5382         else {
5383             step = PyNumber_AsSsize_t(slice->step,
5384                                       PyExc_ValueError);
5385             if (step == -1 && PyErr_Occurred())
5386                 return NULL;
5387             if (step == 0) {
5388                 PyErr_SetString(PyExc_ValueError,
5389                                 "slice step cannot be zero");
5390                 return NULL;
5391             }
5392         }
5393         if (slice->start == Py_None) {
5394             if (step < 0) {
5395                 PyErr_SetString(PyExc_ValueError,
5396                                 "slice start is required "
5397                                 "for step < 0");
5398                 return NULL;
5399             }
5400             start = 0;
5401         }
5402         else {
5403             start = PyNumber_AsSsize_t(slice->start,
5404                                        PyExc_ValueError);
5405             if (start == -1 && PyErr_Occurred())
5406                 return NULL;
5407         }
5408         if (slice->stop == Py_None) {
5409             PyErr_SetString(PyExc_ValueError,
5410                             "slice stop is required");
5411             return NULL;
5412         }
5413         stop = PyNumber_AsSsize_t(slice->stop,
5414                                   PyExc_ValueError);
5415         if (stop == -1 && PyErr_Occurred())
5416             return NULL;
5417         if ((step > 0 && start > stop) ||
5418             (step < 0 && start < stop))
5419             len = 0;
5420         else if (step > 0)
5421             len = (stop - start - 1) / step + 1;
5422         else
5423             len = (stop - start + 1) / step + 1;
5424 
5425         ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
5426         StgInfo *stginfo;
5427         if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
5428             return NULL;
5429         }
5430         assert(stginfo); /* Cannot be NULL for pointer instances */
5431         proto = stginfo->proto;
5432         assert(proto);
5433         StgInfo *iteminfo;
5434         if (PyStgInfo_FromType(st, proto, &iteminfo) < 0) {
5435             return NULL;
5436         }
5437         assert(iteminfo);
5438         if (iteminfo->getfunc == _ctypes_get_fielddesc("c")->getfunc) {
5439             char *ptr = *(char **)self->b_ptr;
5440             char *dest;
5441 
5442             if (len <= 0)
5443                 return PyBytes_FromStringAndSize("", 0);
5444             if (step == 1) {
5445                 return PyBytes_FromStringAndSize(ptr + start,
5446                                                  len);
5447             }
5448             dest = (char *)PyMem_Malloc(len);
5449             if (dest == NULL)
5450                 return PyErr_NoMemory();
5451             for (cur = start, i = 0; i < len; cur += step, i++) {
5452                 dest[i] = ptr[cur];
5453             }
5454             np = PyBytes_FromStringAndSize(dest, len);
5455             PyMem_Free(dest);
5456             return np;
5457         }
5458         if (iteminfo->getfunc == _ctypes_get_fielddesc("u")->getfunc) {
5459             wchar_t *ptr = *(wchar_t **)self->b_ptr;
5460             wchar_t *dest;
5461 
5462             if (len <= 0)
5463                 return PyUnicode_New(0, 0);
5464             if (step == 1) {
5465                 return PyUnicode_FromWideChar(ptr + start,
5466                                               len);
5467             }
5468             dest = PyMem_New(wchar_t, len);
5469             if (dest == NULL)
5470                 return PyErr_NoMemory();
5471             for (cur = start, i = 0; i < len; cur += step, i++) {
5472                 dest[i] = ptr[cur];
5473             }
5474             np = PyUnicode_FromWideChar(dest, len);
5475             PyMem_Free(dest);
5476             return np;
5477         }
5478 
5479         np = PyList_New(len);
5480         if (np == NULL)
5481             return NULL;
5482 
5483         for (cur = start, i = 0; i < len; cur += step, i++) {
5484             PyObject *v = Pointer_item(myself, cur);
5485             PyList_SET_ITEM(np, i, v);
5486         }
5487         return np;
5488     }
5489     else {
5490         PyErr_SetString(PyExc_TypeError,
5491                         "Pointer indices must be integer");
5492         return NULL;
5493     }
5494 }
5495 
5496 static int
Pointer_bool(CDataObject * self)5497 Pointer_bool(CDataObject *self)
5498 {
5499     return (*(void **)self->b_ptr != NULL);
5500 }
5501 
5502 static PyType_Slot pycpointer_slots[] = {
5503     {Py_tp_doc, PyDoc_STR("XXX to be provided")},
5504     {Py_tp_getset, Pointer_getsets},
5505     {Py_tp_init, Pointer_init},
5506     {Py_tp_new, Pointer_new},
5507     {Py_bf_getbuffer, PyCData_NewGetBuffer},
5508     {Py_nb_bool, Pointer_bool},
5509     {Py_mp_subscript, Pointer_subscript},
5510     {Py_sq_item, Pointer_item},
5511     {Py_sq_ass_item, Pointer_ass_item},
5512     {0, NULL},
5513 };
5514 
5515 static PyType_Spec pycpointer_spec = {
5516     .name = "_ctypes._Pointer",
5517     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
5518               Py_TPFLAGS_IMMUTABLETYPE),
5519     .slots = pycpointer_slots,
5520 };
5521 
5522 /******************************************************************/
5523 /*
5524  *  Module initialization.
5525  */
5526 
5527 PyDoc_STRVAR(_ctypes__doc__,
5528 "Create and manipulate C compatible data types in Python.");
5529 
5530 #ifdef MS_WIN32
5531 
5532 PyDoc_STRVAR(comerror_doc, "Raised when a COM method call failed.");
5533 
5534 int
comerror_init(PyObject * self,PyObject * args,PyObject * kwds)5535 comerror_init(PyObject *self, PyObject *args, PyObject *kwds)
5536 {
5537     PyObject *hresult, *text, *details;
5538     PyObject *a;
5539     int status;
5540 
5541     if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
5542         return -1;
5543 
5544     if (!PyArg_ParseTuple(args, "OOO:COMError", &hresult, &text, &details))
5545         return -1;
5546 
5547     a = PySequence_GetSlice(args, 1, PyTuple_GET_SIZE(args));
5548     if (!a)
5549         return -1;
5550     status = PyObject_SetAttrString(self, "args", a);
5551     Py_DECREF(a);
5552     if (status < 0)
5553         return -1;
5554 
5555     if (PyObject_SetAttrString(self, "hresult", hresult) < 0)
5556         return -1;
5557 
5558     if (PyObject_SetAttrString(self, "text", text) < 0)
5559         return -1;
5560 
5561     if (PyObject_SetAttrString(self, "details", details) < 0)
5562         return -1;
5563 
5564     Py_INCREF(args);
5565     Py_SETREF(((PyBaseExceptionObject *)self)->args, args);
5566 
5567     return 0;
5568 }
5569 
5570 static int
comerror_clear(PyObject * self)5571 comerror_clear(PyObject *self)
5572 {
5573     return ((PyTypeObject *)PyExc_BaseException)->tp_clear(self);
5574 }
5575 
5576 static int
comerror_traverse(PyObject * self,visitproc visit,void * arg)5577 comerror_traverse(PyObject *self, visitproc visit, void *arg)
5578 {
5579     Py_VISIT(Py_TYPE(self));
5580     return ((PyTypeObject *)PyExc_BaseException)->tp_traverse(self, visit, arg);
5581 }
5582 
5583 static void
comerror_dealloc(PyObject * self)5584 comerror_dealloc(PyObject *self)
5585 {
5586     PyTypeObject *tp = Py_TYPE(self);
5587     PyObject_GC_UnTrack(self);
5588     (void)comerror_clear(self);
5589     tp->tp_free(self);
5590     Py_DECREF(tp);
5591 }
5592 
5593 static PyType_Slot comerror_slots[] = {
5594     {Py_tp_doc, (void *)PyDoc_STR(comerror_doc)},
5595     {Py_tp_init, comerror_init},
5596     {Py_tp_traverse, comerror_traverse},
5597     {Py_tp_dealloc, comerror_dealloc},
5598     {Py_tp_clear, comerror_clear},
5599     {0, NULL},
5600 };
5601 
5602 static PyType_Spec comerror_spec = {
5603     .name = "_ctypes.COMError",
5604     .basicsize = sizeof(PyBaseExceptionObject),
5605     .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
5606               Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE),
5607     .slots = comerror_slots,
5608 };
5609 
5610 #endif  // MS_WIN32
5611 
5612 static PyObject *
string_at(const char * ptr,int size)5613 string_at(const char *ptr, int size)
5614 {
5615     if (PySys_Audit("ctypes.string_at", "ni", (Py_ssize_t)ptr, size) < 0) {
5616         return NULL;
5617     }
5618     if (size == -1)
5619         return PyBytes_FromStringAndSize(ptr, strlen(ptr));
5620     return PyBytes_FromStringAndSize(ptr, size);
5621 }
5622 
5623 static int
cast_check_pointertype(ctypes_state * st,PyObject * arg)5624 cast_check_pointertype(ctypes_state *st, PyObject *arg)
5625 {
5626     if (PyCPointerTypeObject_Check(st, arg)) {
5627         return 1;
5628     }
5629     if (PyCFuncPtrTypeObject_Check(st, arg)) {
5630         return 1;
5631     }
5632     StgInfo *info;
5633     if (PyStgInfo_FromType(st, arg, &info) < 0) {
5634         return 0;
5635     }
5636     if (info != NULL && info->proto != NULL) {
5637         if (PyUnicode_Check(info->proto)
5638             && (strchr("sPzUZXO", PyUnicode_AsUTF8(info->proto)[0]))) {
5639             /* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
5640             return 1;
5641         }
5642     }
5643     PyErr_Format(PyExc_TypeError,
5644                  "cast() argument 2 must be a pointer type, not %s",
5645                  PyType_Check(arg)
5646                  ? ((PyTypeObject *)arg)->tp_name
5647                  : Py_TYPE(arg)->tp_name);
5648     return 0;
5649 }
5650 
5651 static PyObject *
cast(void * ptr,PyObject * src,PyObject * ctype)5652 cast(void *ptr, PyObject *src, PyObject *ctype)
5653 {
5654     PyObject *mod = PyType_GetModuleByDef(Py_TYPE(ctype), &_ctypesmodule);
5655     if (!mod) {
5656         PyErr_SetString(PyExc_TypeError,
5657                         "cast() argument 2 must be a pointer type");
5658         return NULL;
5659     }
5660     ctypes_state *st = get_module_state(mod);
5661 
5662     CDataObject *result;
5663     if (cast_check_pointertype(st, ctype) == 0) {
5664         return NULL;
5665     }
5666     result = (CDataObject *)_PyObject_CallNoArgs(ctype);
5667     if (result == NULL)
5668         return NULL;
5669 
5670     /*
5671       The casted objects '_objects' member:
5672 
5673       It must certainly contain the source objects one.
5674       It must contain the source object itself.
5675      */
5676     if (CDataObject_Check(st, src)) {
5677         CDataObject *obj = (CDataObject *)src;
5678         CDataObject *container;
5679 
5680         /* PyCData_GetContainer will initialize src.b_objects, we need
5681            this so it can be shared */
5682         container = PyCData_GetContainer(obj);
5683         if (container == NULL)
5684             goto failed;
5685 
5686         /* But we need a dictionary! */
5687         if (obj->b_objects == Py_None) {
5688             Py_DECREF(Py_None);
5689             obj->b_objects = PyDict_New();
5690             if (obj->b_objects == NULL)
5691                 goto failed;
5692         }
5693         result->b_objects = Py_XNewRef(obj->b_objects);
5694         if (result->b_objects && PyDict_CheckExact(result->b_objects)) {
5695             PyObject *index;
5696             int rc;
5697             index = PyLong_FromVoidPtr((void *)src);
5698             if (index == NULL)
5699                 goto failed;
5700             rc = PyDict_SetItem(result->b_objects, index, src);
5701             Py_DECREF(index);
5702             if (rc == -1)
5703                 goto failed;
5704         }
5705     }
5706     /* Should we assert that result is a pointer type? */
5707     memcpy(result->b_ptr, &ptr, sizeof(void *));
5708     return (PyObject *)result;
5709 
5710   failed:
5711     Py_DECREF(result);
5712     return NULL;
5713 }
5714 
5715 
5716 static PyObject *
wstring_at(const wchar_t * ptr,int size)5717 wstring_at(const wchar_t *ptr, int size)
5718 {
5719     Py_ssize_t ssize = size;
5720     if (PySys_Audit("ctypes.wstring_at", "nn", (Py_ssize_t)ptr, ssize) < 0) {
5721         return NULL;
5722     }
5723     if (ssize == -1)
5724         ssize = wcslen(ptr);
5725     return PyUnicode_FromWideChar(ptr, ssize);
5726 }
5727 
5728 
5729 static int
_ctypes_add_types(PyObject * mod)5730 _ctypes_add_types(PyObject *mod)
5731 {
5732 #define TYPE_READY(TYPE) \
5733     if (PyType_Ready(TYPE) < 0) { \
5734         return -1; \
5735     }
5736 #define CREATE_TYPE(TP, SPEC, META, BASE) do {                      \
5737     PyObject *type = PyType_FromMetaclass(META, mod, SPEC,          \
5738                                           (PyObject *)BASE);        \
5739     if (type == NULL) {                                             \
5740         return -1;                                                  \
5741     }                                                               \
5742     TP = (PyTypeObject *)type;                                      \
5743 } while (0)
5744 
5745 #define MOD_ADD_TYPE(TP, SPEC, META, BASE) do {                     \
5746     CREATE_TYPE(TP, SPEC, META, BASE);                              \
5747     if (PyModule_AddType(mod, (PyTypeObject *)(TP)) < 0) {          \
5748         return -1;                                                  \
5749     }                                                               \
5750 } while (0)
5751 
5752     ctypes_state *st = get_module_state(mod);
5753 
5754     /* Note:
5755        ob_type is the metatype (the 'type'), defaults to PyType_Type,
5756        tp_base is the base type, defaults to 'object' aka PyBaseObject_Type.
5757     */
5758     CREATE_TYPE(st->PyCArg_Type, &carg_spec, NULL, NULL);
5759     CREATE_TYPE(st->PyCThunk_Type, &cthunk_spec, NULL, NULL);
5760     CREATE_TYPE(st->PyCData_Type, &pycdata_spec, NULL, NULL);
5761 
5762     // Common Metaclass
5763     CREATE_TYPE(st->PyCType_Type, &pyctype_type_spec,
5764                 NULL, &PyType_Type);
5765 
5766     /*************************************************
5767      *
5768      * Metaclasses
5769      */
5770     CREATE_TYPE(st->PyCStructType_Type, &pycstruct_type_spec,
5771                 NULL, st->PyCType_Type);
5772     CREATE_TYPE(st->UnionType_Type, &union_type_spec,
5773                 NULL, st->PyCType_Type);
5774     CREATE_TYPE(st->PyCPointerType_Type, &pycpointer_type_spec,
5775                 NULL, st->PyCType_Type);
5776     CREATE_TYPE(st->PyCArrayType_Type, &pycarray_type_spec,
5777                 NULL, st->PyCType_Type);
5778     CREATE_TYPE(st->PyCSimpleType_Type, &pycsimple_type_spec,
5779                 NULL, st->PyCType_Type);
5780     CREATE_TYPE(st->PyCFuncPtrType_Type, &pycfuncptr_type_spec,
5781                 NULL, st->PyCType_Type);
5782 
5783     /*************************************************
5784      *
5785      * Classes using a custom metaclass
5786      */
5787 
5788     MOD_ADD_TYPE(st->Struct_Type, &pycstruct_spec,
5789                  st->PyCStructType_Type, st->PyCData_Type);
5790     MOD_ADD_TYPE(st->Union_Type, &pycunion_spec,
5791                  st->UnionType_Type, st->PyCData_Type);
5792     MOD_ADD_TYPE(st->PyCPointer_Type, &pycpointer_spec,
5793                  st->PyCPointerType_Type, st->PyCData_Type);
5794     MOD_ADD_TYPE(st->PyCArray_Type, &pycarray_spec,
5795                  st->PyCArrayType_Type, st->PyCData_Type);
5796     MOD_ADD_TYPE(st->Simple_Type, &pycsimple_spec,
5797                  st->PyCSimpleType_Type, st->PyCData_Type);
5798     MOD_ADD_TYPE(st->PyCFuncPtr_Type, &pycfuncptr_spec,
5799                  st->PyCFuncPtrType_Type, st->PyCData_Type);
5800 
5801     /*************************************************
5802      *
5803      * Simple classes
5804      */
5805 
5806     CREATE_TYPE(st->PyCField_Type, &cfield_spec, NULL, NULL);
5807 
5808     /*************************************************
5809      *
5810      * Other stuff
5811      */
5812 
5813     CREATE_TYPE(st->DictRemover_Type, &dictremover_spec, NULL, NULL);
5814     CREATE_TYPE(st->StructParam_Type, &structparam_spec, NULL, NULL);
5815 
5816 #ifdef MS_WIN32
5817     CREATE_TYPE(st->PyComError_Type, &comerror_spec, NULL, PyExc_Exception);
5818 #endif
5819 
5820 #undef TYPE_READY
5821 #undef MOD_ADD_TYPE
5822 #undef CREATE_TYPE
5823     return 0;
5824 }
5825 
5826 
5827 static int
_ctypes_add_objects(PyObject * mod)5828 _ctypes_add_objects(PyObject *mod)
5829 {
5830 #define MOD_ADD(name, expr) \
5831     do { \
5832         if (PyModule_Add(mod, name, (expr)) < 0) { \
5833             return -1; \
5834         } \
5835     } while (0)
5836 
5837     ctypes_state *st = get_module_state(mod);
5838     MOD_ADD("_pointer_type_cache", Py_NewRef(st->_ctypes_ptrtype_cache));
5839 
5840 #ifdef MS_WIN32
5841     MOD_ADD("COMError", Py_NewRef(st->PyComError_Type));
5842     MOD_ADD("FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
5843     MOD_ADD("FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL));
5844 #endif
5845     MOD_ADD("FUNCFLAG_CDECL", PyLong_FromLong(FUNCFLAG_CDECL));
5846     MOD_ADD("FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
5847     MOD_ADD("FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
5848     MOD_ADD("FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
5849     MOD_ADD("__version__", PyUnicode_FromString("1.1.0"));
5850 
5851     MOD_ADD("_memmove_addr", PyLong_FromVoidPtr(memmove));
5852     MOD_ADD("_memset_addr", PyLong_FromVoidPtr(memset));
5853     MOD_ADD("_string_at_addr", PyLong_FromVoidPtr(string_at));
5854     MOD_ADD("_cast_addr", PyLong_FromVoidPtr(cast));
5855     MOD_ADD("_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
5856 
5857 /* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
5858 #if !HAVE_DECL_RTLD_LOCAL
5859 #  define RTLD_LOCAL 0
5860 #endif
5861 
5862 /* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
5863    RTLD_LOCAL. */
5864 #if !HAVE_DECL_RTLD_GLOBAL
5865 #  define RTLD_GLOBAL RTLD_LOCAL
5866 #endif
5867     MOD_ADD("RTLD_LOCAL", PyLong_FromLong(RTLD_LOCAL));
5868     MOD_ADD("RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL));
5869     MOD_ADD("CTYPES_MAX_ARGCOUNT", PyLong_FromLong(CTYPES_MAX_ARGCOUNT));
5870     MOD_ADD("ArgumentError", Py_NewRef(st->PyExc_ArgError));
5871     MOD_ADD("SIZEOF_TIME_T", PyLong_FromSsize_t(SIZEOF_TIME_T));
5872     return 0;
5873 #undef MOD_ADD
5874 }
5875 
5876 
5877 static int
_ctypes_mod_exec(PyObject * mod)5878 _ctypes_mod_exec(PyObject *mod)
5879 {
5880     ctypes_state *st = get_module_state(mod);
5881     st->_unpickle = PyObject_GetAttrString(mod, "_unpickle");
5882     if (st->_unpickle == NULL) {
5883         return -1;
5884     }
5885 
5886     st->_ctypes_ptrtype_cache = PyDict_New();
5887     if (st->_ctypes_ptrtype_cache == NULL) {
5888         return -1;
5889     }
5890 
5891     st->PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
5892     if (!st->PyExc_ArgError) {
5893         return -1;
5894     }
5895 
5896     if (_ctypes_add_types(mod) < 0) {
5897         return -1;
5898     }
5899 
5900     if (_ctypes_add_objects(mod) < 0) {
5901         return -1;
5902     }
5903     return 0;
5904 }
5905 
5906 
5907 static int
module_traverse(PyObject * module,visitproc visit,void * arg)5908 module_traverse(PyObject *module, visitproc visit, void *arg) {
5909     ctypes_state *st = get_module_state(module);
5910     Py_VISIT(st->_ctypes_ptrtype_cache);
5911     Py_VISIT(st->_unpickle);
5912     Py_VISIT(st->array_cache);
5913     Py_VISIT(st->error_object_name);
5914     Py_VISIT(st->PyExc_ArgError);
5915     Py_VISIT(st->swapped_suffix);
5916 
5917     Py_VISIT(st->DictRemover_Type);
5918     Py_VISIT(st->PyCArg_Type);
5919     Py_VISIT(st->PyCField_Type);
5920     Py_VISIT(st->PyCThunk_Type);
5921     Py_VISIT(st->StructParam_Type);
5922     Py_VISIT(st->PyCStructType_Type);
5923     Py_VISIT(st->UnionType_Type);
5924     Py_VISIT(st->PyCPointerType_Type);
5925     Py_VISIT(st->PyCArrayType_Type);
5926     Py_VISIT(st->PyCSimpleType_Type);
5927     Py_VISIT(st->PyCFuncPtrType_Type);
5928     Py_VISIT(st->PyCData_Type);
5929     Py_VISIT(st->Struct_Type);
5930     Py_VISIT(st->Union_Type);
5931     Py_VISIT(st->PyCArray_Type);
5932     Py_VISIT(st->Simple_Type);
5933     Py_VISIT(st->PyCPointer_Type);
5934     Py_VISIT(st->PyCFuncPtr_Type);
5935 #ifdef MS_WIN32
5936     Py_VISIT(st->PyComError_Type);
5937 #endif
5938     Py_VISIT(st->PyCType_Type);
5939     return 0;
5940 }
5941 
5942 static int
module_clear(PyObject * module)5943 module_clear(PyObject *module) {
5944     ctypes_state *st = get_module_state(module);
5945     Py_CLEAR(st->_ctypes_ptrtype_cache);
5946     Py_CLEAR(st->_unpickle);
5947     Py_CLEAR(st->array_cache);
5948     Py_CLEAR(st->error_object_name);
5949     Py_CLEAR(st->PyExc_ArgError);
5950     Py_CLEAR(st->swapped_suffix);
5951 
5952     Py_CLEAR(st->DictRemover_Type);
5953     Py_CLEAR(st->PyCArg_Type);
5954     Py_CLEAR(st->PyCField_Type);
5955     Py_CLEAR(st->PyCThunk_Type);
5956     Py_CLEAR(st->StructParam_Type);
5957     Py_CLEAR(st->PyCStructType_Type);
5958     Py_CLEAR(st->UnionType_Type);
5959     Py_CLEAR(st->PyCPointerType_Type);
5960     Py_CLEAR(st->PyCArrayType_Type);
5961     Py_CLEAR(st->PyCSimpleType_Type);
5962     Py_CLEAR(st->PyCFuncPtrType_Type);
5963     Py_CLEAR(st->PyCData_Type);
5964     Py_CLEAR(st->Struct_Type);
5965     Py_CLEAR(st->Union_Type);
5966     Py_CLEAR(st->PyCArray_Type);
5967     Py_CLEAR(st->Simple_Type);
5968     Py_CLEAR(st->PyCPointer_Type);
5969     Py_CLEAR(st->PyCFuncPtr_Type);
5970 #ifdef MS_WIN32
5971     Py_CLEAR(st->PyComError_Type);
5972 #endif
5973     Py_CLEAR(st->PyCType_Type);
5974     return 0;
5975 }
5976 
5977 static void
module_free(void * module)5978 module_free(void *module)
5979 {
5980     (void)module_clear((PyObject *)module);
5981 }
5982 
5983 static PyModuleDef_Slot module_slots[] = {
5984     {Py_mod_exec, _ctypes_mod_exec},
5985     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
5986     {Py_mod_gil, Py_MOD_GIL_NOT_USED},
5987     {0, NULL}
5988 };
5989 
5990 struct PyModuleDef _ctypesmodule = {
5991     PyModuleDef_HEAD_INIT,
5992     .m_name = "_ctypes",
5993     .m_doc = _ctypes__doc__,
5994     .m_size = sizeof(ctypes_state),
5995     .m_methods = _ctypes_module_methods,
5996     .m_slots = module_slots,
5997     .m_traverse = module_traverse,
5998     .m_clear = module_clear,
5999     .m_free = module_free,
6000 };
6001 
6002 PyMODINIT_FUNC
PyInit__ctypes(void)6003 PyInit__ctypes(void)
6004 {
6005     return PyModuleDef_Init(&_ctypesmodule);
6006 }
6007 
6008 /*
6009  Local Variables:
6010  compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
6011  End:
6012 */
6013