@@ -3396,6 +3396,9 @@ generic_pycdata_new(ctypes_state *st,
33963396 PyCFuncPtr_Type
33973397*/
33983398
3399+ static int
3400+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3401+
33993402static int
34003403PyCFuncPtr_set_errcheck (PyCFuncPtrObject * self , PyObject * ob , void * Py_UNUSED (ignored ))
34013404{
@@ -3470,21 +3473,26 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
34703473}
34713474
34723475static int
3473- PyCFuncPtr_set_argtypes (PyCFuncPtrObject * self , PyObject * ob , void * Py_UNUSED (ignored ))
3476+ PyCFuncPtr_set_argtypes (PyCFuncPtrObject * self , PyObject * value , void * Py_UNUSED (ignored ))
34743477{
3475- PyObject * converters ;
3476-
3477- if (ob == NULL || ob == Py_None ) {
3478+ if (value == NULL || value == Py_None ) {
34783479 Py_CLEAR (self -> converters );
34793480 Py_CLEAR (self -> argtypes );
34803481 } else {
3481- ctypes_state * st = get_module_state_by_def (Py_TYPE (Py_TYPE (self )));
3482- converters = converters_from_argtypes (st , ob );
3482+ PyTypeObject * type = Py_TYPE (self );
3483+ ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3484+ PyObject * converters = converters_from_argtypes (st , value );
34833485 if (!converters )
34843486 return -1 ;
3487+
3488+ /* Verify paramflags again due to constraints with argtypes */
3489+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3490+ Py_DECREF (converters );
3491+ return -1 ;
3492+ }
34853493 Py_XSETREF (self -> converters , converters );
3486- Py_INCREF (ob );
3487- Py_XSETREF (self -> argtypes , ob );
3494+ Py_INCREF (value );
3495+ Py_XSETREF (self -> argtypes , value );
34883496 }
34893497 return 0 ;
34903498}
@@ -3606,10 +3614,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
36063614
36073615/* Returns 1 on success, 0 on error */
36083616static int
3609- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3617+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
36103618{
36113619 Py_ssize_t i , len ;
3612- PyObject * argtypes ;
36133620
36143621 StgInfo * info ;
36153622 if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3620,10 +3627,13 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
36203627 "abstract class" );
36213628 return 0 ;
36223629 }
3623- argtypes = info -> argtypes ;
3630+ if (argtypes == NULL ) {
3631+ argtypes = info -> argtypes ;
3632+ }
36243633
3625- if (paramflags == NULL || info -> argtypes == NULL )
3634+ if (paramflags == NULL || argtypes == NULL ) {
36263635 return 1 ;
3636+ }
36273637
36283638 if (!PyTuple_Check (paramflags )) {
36293639 PyErr_SetString (PyExc_TypeError ,
@@ -3632,7 +3642,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
36323642 }
36333643
36343644 len = PyTuple_GET_SIZE (paramflags );
3635- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3645+ if (len != PyTuple_GET_SIZE (argtypes )) {
36363646 PyErr_SetString (PyExc_ValueError ,
36373647 "paramflags must have the same length as argtypes" );
36383648 return 0 ;
@@ -3807,7 +3817,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
38073817#endif
38083818#undef USE_DLERROR
38093819 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3810- if (!_validate_paramflags (st , type , paramflags )) {
3820+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
38113821 Py_DECREF (ftuple );
38123822 return NULL ;
38133823 }
@@ -3849,7 +3859,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
38493859 paramflags = NULL ;
38503860
38513861 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3852- if (!_validate_paramflags (st , type , paramflags )) {
3862+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
38533863 return NULL ;
38543864 }
38553865 self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments