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