@@ -3628,6 +3628,9 @@ atomic_xgetref(PyObject *obj, PyObject **field)
36283628#endif
36293629}
36303630
3631+ static int
3632+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3633+
36313634
36323635
36333636/*[clinic input]
@@ -3741,16 +3744,22 @@ static int
37413744_ctypes_CFuncPtr_argtypes_set_impl (PyCFuncPtrObject * self , PyObject * value )
37423745/*[clinic end generated code: output=596a36e2ae89d7d1 input=c4627573e980aa8b]*/
37433746{
3744- PyObject * converters ;
3745-
37463747 if (value == NULL || value == Py_None ) {
37473748 atomic_xsetref (& self -> argtypes , NULL );
37483749 atomic_xsetref (& self -> converters , NULL );
37493750 } else {
3750- ctypes_state * st = get_module_state_by_def (Py_TYPE (Py_TYPE (self )));
3751- converters = converters_from_argtypes (st , value );
3751+ PyTypeObject * type = Py_TYPE (self );
3752+ ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3753+
3754+ PyObject * converters = converters_from_argtypes (st , value );
37523755 if (!converters )
37533756 return -1 ;
3757+
3758+ /* Verify paramflags again due to constraints with argtypes */
3759+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3760+ Py_DECREF (converters );
3761+ return -1 ;
3762+ }
37543763 atomic_xsetref (& self -> converters , converters );
37553764 Py_INCREF (value );
37563765 atomic_xsetref (& self -> argtypes , value );
@@ -3880,10 +3889,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
38803889
38813890/* Returns 1 on success, 0 on error */
38823891static int
3883- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3892+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
38843893{
38853894 Py_ssize_t i , len ;
3886- PyObject * argtypes ;
38873895
38883896 StgInfo * info ;
38893897 if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3894,10 +3902,13 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
38943902 "abstract class" );
38953903 return 0 ;
38963904 }
3897- argtypes = info -> argtypes ;
3905+ if (argtypes == NULL ) {
3906+ argtypes = info -> argtypes ;
3907+ }
38983908
3899- if (paramflags == NULL || info -> argtypes == NULL )
3909+ if (paramflags == NULL || argtypes == NULL ) {
39003910 return 1 ;
3911+ }
39013912
39023913 if (!PyTuple_Check (paramflags )) {
39033914 PyErr_SetString (PyExc_TypeError ,
@@ -3906,7 +3917,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
39063917 }
39073918
39083919 len = PyTuple_GET_SIZE (paramflags );
3909- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3920+ if (len != PyTuple_GET_SIZE (argtypes )) {
39103921 PyErr_SetString (PyExc_ValueError ,
39113922 "paramflags must have the same length as argtypes" );
39123923 return 0 ;
@@ -4082,7 +4093,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
40824093#endif
40834094#undef USE_DLERROR
40844095 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4085- if (!_validate_paramflags (st , type , paramflags )) {
4096+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
40864097 Py_DECREF (ftuple );
40874098 return NULL ;
40884099 }
@@ -4126,7 +4137,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
41264137 paramflags = NULL ;
41274138
41284139 ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4129- if (!_validate_paramflags (st , type , paramflags )) {
4140+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
41304141 return NULL ;
41314142 }
41324143 self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments