@@ -3634,6 +3634,9 @@ atomic_xgetref(PyObject *obj, PyObject **field)
3634
3634
#endif
3635
3635
}
3636
3636
3637
+ static int
3638
+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes );
3639
+
3637
3640
3638
3641
3639
3642
/*[clinic input]
@@ -3747,16 +3750,22 @@ static int
3747
3750
_ctypes_CFuncPtr_argtypes_set_impl (PyCFuncPtrObject * self , PyObject * value )
3748
3751
/*[clinic end generated code: output=596a36e2ae89d7d1 input=c4627573e980aa8b]*/
3749
3752
{
3750
- PyObject * converters ;
3751
-
3752
3753
if (value == NULL || value == Py_None ) {
3753
3754
atomic_xsetref (& self -> argtypes , NULL );
3754
3755
atomic_xsetref (& self -> converters , NULL );
3755
3756
} else {
3756
- ctypes_state * st = get_module_state_by_def (Py_TYPE (Py_TYPE (self )));
3757
- converters = converters_from_argtypes (st , value );
3757
+ PyTypeObject * type = Py_TYPE (self );
3758
+ ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
3759
+
3760
+ PyObject * converters = converters_from_argtypes (st , value );
3758
3761
if (!converters )
3759
3762
return -1 ;
3763
+
3764
+ /* Verify paramflags again due to constraints with argtypes */
3765
+ if (!_validate_paramflags (st , type , self -> paramflags , value )) {
3766
+ Py_DECREF (converters );
3767
+ return -1 ;
3768
+ }
3760
3769
atomic_xsetref (& self -> converters , converters );
3761
3770
Py_INCREF (value );
3762
3771
atomic_xsetref (& self -> argtypes , value );
@@ -3886,10 +3895,9 @@ _check_outarg_type(ctypes_state *st, PyObject *arg, Py_ssize_t index)
3886
3895
3887
3896
/* Returns 1 on success, 0 on error */
3888
3897
static int
3889
- _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags )
3898
+ _validate_paramflags (ctypes_state * st , PyTypeObject * type , PyObject * paramflags , PyObject * argtypes )
3890
3899
{
3891
3900
Py_ssize_t i , len ;
3892
- PyObject * argtypes ;
3893
3901
3894
3902
StgInfo * info ;
3895
3903
if (PyStgInfo_FromType (st , (PyObject * )type , & info ) < 0 ) {
@@ -3900,10 +3908,13 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
3900
3908
"abstract class" );
3901
3909
return 0 ;
3902
3910
}
3903
- argtypes = info -> argtypes ;
3911
+ if (argtypes == NULL ) {
3912
+ argtypes = info -> argtypes ;
3913
+ }
3904
3914
3905
- if (paramflags == NULL || info -> argtypes == NULL )
3915
+ if (paramflags == NULL || argtypes == NULL ) {
3906
3916
return 1 ;
3917
+ }
3907
3918
3908
3919
if (!PyTuple_Check (paramflags )) {
3909
3920
PyErr_SetString (PyExc_TypeError ,
@@ -3912,7 +3923,7 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
3912
3923
}
3913
3924
3914
3925
len = PyTuple_GET_SIZE (paramflags );
3915
- if (len != PyTuple_GET_SIZE (info -> argtypes )) {
3926
+ if (len != PyTuple_GET_SIZE (argtypes )) {
3916
3927
PyErr_SetString (PyExc_ValueError ,
3917
3928
"paramflags must have the same length as argtypes" );
3918
3929
return 0 ;
@@ -4088,7 +4099,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
4088
4099
#endif
4089
4100
#undef USE_DLERROR
4090
4101
ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4091
- if (!_validate_paramflags (st , type , paramflags )) {
4102
+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
4092
4103
Py_DECREF (ftuple );
4093
4104
return NULL ;
4094
4105
}
@@ -4132,7 +4143,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
4132
4143
paramflags = NULL ;
4133
4144
4134
4145
ctypes_state * st = get_module_state_by_def (Py_TYPE (type ));
4135
- if (!_validate_paramflags (st , type , paramflags )) {
4146
+ if (!_validate_paramflags (st , type , paramflags , NULL )) {
4136
4147
return NULL ;
4137
4148
}
4138
4149
self = (PyCFuncPtrObject * )generic_pycdata_new (st , type , args , kwds );
0 commit comments