@@ -3628,6 +3628,9 @@ atomic_xgetref(PyObject *obj, PyObject **field)
3628
3628
#endif
3629
3629
}
3630
3630
3631
+ static int
3632
+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3633
+
3631
3634
3632
3635
3633
3636
/*[clinic input]
@@ -3741,16 +3744,22 @@ static int
3741
3744
_ctypes_CFuncPtr_argtypes_set_impl (PyCFuncPtrObject * self , PyObject * value )
3742
3745
/*[clinic end generated code: output=596a36e2ae89d7d1 input=c4627573e980aa8b]*/
3743
3746
{
3744
- PyObject * converters ;
3745
-
3746
3747
if (value == NULL || value == Py_None ) {
3747
3748
atomic_xsetref (& self -> argtypes , NULL );
3748
3749
atomic_xsetref (& self -> converters , NULL );
3749
3750
} 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 );
3752
3755
if (!converters )
3753
3756
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
+ }
3754
3763
atomic_xsetref (& self -> converters , converters );
3755
3764
Py_INCREF (value );
3756
3765
atomic_xsetref (& self -> argtypes , value );
@@ -3880,10 +3889,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
3880
3889
3881
3890
/* Returns 1 on success, 0 on error */
3882
3891
static int
3883
- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3892
+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
3884
3893
{
3885
3894
Py_ssize_t i , len ;
3886
- PyObject * argtypes ;
3887
3895
3888
3896
StgInfo * info ;
3889
3897
if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3894,10 +3902,13 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
3894
3902
"abstract class" );
3895
3903
return 0 ;
3896
3904
}
3897
- argtypes = info -> argtypes ;
3905
+ if (argtypes == NULL ) {
3906
+ argtypes = info -> argtypes ;
3907
+ }
3898
3908
3899
- if (paramflags == NULL || info -> argtypes == NULL )
3909
+ if (paramflags == NULL || argtypes == NULL ) {
3900
3910
return 1 ;
3911
+ }
3901
3912
3902
3913
if (!PyTuple_Check (paramflags )) {
3903
3914
PyErr_SetString (PyExc_TypeError ,
@@ -3906,7 +3917,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
3906
3917
}
3907
3918
3908
3919
len = PyTuple_GET_SIZE (paramflags );
3909
- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3920
+ if (len != PyTuple_GET_SIZE (argtypes )) {
3910
3921
PyErr_SetString (PyExc_ValueError ,
3911
3922
"paramflags must have the same length as argtypes" );
3912
3923
return 0 ;
@@ -4082,7 +4093,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
4082
4093
#endif
4083
4094
#undef USE_DLERROR
4084
4095
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 )) {
4086
4097
Py_DECREF (ftuple );
4087
4098
return NULL ;
4088
4099
}
@@ -4126,7 +4137,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
4126
4137
paramflags = NULL ;
4127
4138
4128
4139
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 )) {
4130
4141
return NULL ;
4131
4142
}
4132
4143
self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments