diff options
author | Charlie Zhao <zhaoyu_hit@qq.com> | 2023-07-30 08:28:54 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-30 08:28:54 (GMT) |
commit | 3979150a0d406707f6d253d7c15fb32c1e005a77 (patch) | |
tree | 229ea5e859a0c08788d81da41d1e80474f5b3c9b /Modules | |
parent | 5113ed7a2b92e8beabebe5fe2f6e856c52fbe1a0 (diff) | |
download | cpython-3979150a0d406707f6d253d7c15fb32c1e005a77.zip cpython-3979150a0d406707f6d253d7c15fb32c1e005a77.tar.gz cpython-3979150a0d406707f6d253d7c15fb32c1e005a77.tar.bz2 |
gh-106263: Fix segfault in `signaldict_repr` in `_decimal` module (#106270)
Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_decimal/_decimal.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 7a20697..585214c 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -314,14 +314,12 @@ value_error_int(const char *mesg) return -1; } -#ifdef CONFIG_32 static PyObject * value_error_ptr(const char *mesg) { PyErr_SetString(PyExc_ValueError, mesg); return NULL; } -#endif static int type_error_int(const char *mesg) @@ -608,6 +606,8 @@ getround(decimal_state *state, PyObject *v) initialized to new SignalDicts. Once a SignalDict is tied to a context, it cannot be deleted. */ +static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict"; + static int signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) { @@ -616,14 +616,20 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) } static Py_ssize_t -signaldict_len(PyObject *self UNUSED) +signaldict_len(PyObject *self) { + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } return SIGNAL_MAP_LEN; } static PyObject * signaldict_iter(PyObject *self) { + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return PyTuple_Type.tp_iter(state->SignalTuple); } @@ -632,6 +638,9 @@ static PyObject * signaldict_getitem(PyObject *self, PyObject *key) { uint32_t flag; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } decimal_state *state = get_module_state_by_def(Py_TYPE(self)); flag = exception_as_flag(state, key); @@ -648,11 +657,15 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) uint32_t flag; int x; - decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } + if (value == NULL) { return value_error_int("signal keys cannot be deleted"); } + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); flag = exception_as_flag(state, key); if (flag & DEC_ERRORS) { return -1; @@ -697,6 +710,10 @@ signaldict_repr(PyObject *self) const char *b[SIGNAL_MAP_LEN]; /* bool */ int i; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + assert(SIGNAL_MAP_LEN == 9); decimal_state *state = get_module_state_by_def(Py_TYPE(self)); @@ -721,6 +738,10 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) decimal_state *state = find_state_left_or_right(v, w); assert(PyDecSignalDict_Check(state, v)); + if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + if (op == Py_EQ || op == Py_NE) { if (PyDecSignalDict_Check(state, w)) { res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; @@ -748,6 +769,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) static PyObject * signaldict_copy(PyObject *self, PyObject *args UNUSED) { + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return flags_as_dict(state, SdFlags(self)); } |