diff --git a/CHANGES/9999.bugfix.rst b/CHANGES/9999.bugfix.rst new file mode 100644 index 000000000..63cb8adcd --- /dev/null +++ b/CHANGES/9999.bugfix.rst @@ -0,0 +1,2 @@ +Fixed crash in debug builds. + diff --git a/multidict/_multidict.c b/multidict/_multidict.c index 73c002296..c418c9d50 100644 --- a/multidict/_multidict.c +++ b/multidict/_multidict.c @@ -397,7 +397,10 @@ multidict_repr(MultiDictObject *self) PyObject *name = PyObject_GetAttr((PyObject *)Py_TYPE(self), self->state->str_name); if (name == NULL) { + PyObject *etype, *evalue, *etraceback; + PyErr_Fetch(&etype, &evalue, &etraceback); Py_ReprLeave((PyObject *)self); + PyErr_Restore(etype, evalue, etraceback); return NULL; } PyObject *ret = md_repr(self, name, true, true); @@ -539,6 +542,11 @@ static int multidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds) { mod_state *state = get_mod_state_by_def((PyObject *)self); + if (state == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "Failed to retrieve module state for MultiDict"); + return -1; + } PyObject *arg = NULL; Py_ssize_t size = _multidict_extend_parse_args(state, args, kwds, "MultiDict", &arg); @@ -997,6 +1005,12 @@ static int cimultidict_tp_init(MultiDictObject *self, PyObject *args, PyObject *kwds) { mod_state *state = get_mod_state_by_def((PyObject *)self); + if (state == NULL) { + PyErr_SetString( + PyExc_RuntimeError, + "Failed to retrieve module state for CIMultiDictProxy"); + return -1; + } PyObject *arg = NULL; Py_ssize_t size = _multidict_extend_parse_args(state, args, kwds, "CIMultiDict", &arg); @@ -1052,6 +1066,11 @@ multidict_proxy_tp_init(MultiDictProxyObject *self, PyObject *args, PyObject *kwds) { mod_state *state = get_mod_state_by_def((PyObject *)self); + if (state == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "Failed to retrieve module state for MultiDict"); + return -1; + } PyObject *arg = NULL; MultiDictObject *md = NULL; @@ -1306,6 +1325,12 @@ cimultidict_proxy_tp_init(MultiDictProxyObject *self, PyObject *args, PyObject *kwds) { mod_state *state = get_mod_state_by_def((PyObject *)self); + if (state == NULL) { + PyErr_SetString( + PyExc_RuntimeError, + "Failed to retrieve module state for CIMultiDictProxy"); + return -1; + } PyObject *arg = NULL; MultiDictObject *md = NULL; diff --git a/multidict/_multilib/state.h b/multidict/_multilib/state.h index 4e2610b6c..76d610833 100644 --- a/multidict/_multilib/state.h +++ b/multidict/_multilib/state.h @@ -121,7 +121,12 @@ get_mod_state_by_def(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); PyObject *mod = PyType_GetModuleByDef(tp, &multidict_module); - assert(mod != NULL); + if (mod == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Clear(); + } + return NULL; + } return get_mod_state(mod); }