mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
[3.12] gh-106263: Fix segfault in signaldict_repr
in _decimal
module (#… (#107491)
Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
(cherry picked from commit 3979150a0d
)
This commit is contained in:
parent
8f080a290b
commit
99518bbbf4
4 changed files with 59 additions and 3 deletions
|
@ -5682,6 +5682,36 @@ class CWhitebox(unittest.TestCase):
|
||||||
self.assertEqual(Decimal(400) ** -1, Decimal('0.0025'))
|
self.assertEqual(Decimal(400) ** -1, Decimal('0.0025'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_c_signaldict_segfault(self):
|
||||||
|
# See gh-106263 for details.
|
||||||
|
SignalDict = type(C.Context().flags)
|
||||||
|
sd = SignalDict()
|
||||||
|
err_msg = "invalid signal dict"
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
len(sd)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
iter(sd)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
repr(sd)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
sd[C.InvalidOperation] = True
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
sd[C.InvalidOperation]
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
sd == C.Context().flags
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
C.Context().flags == sd
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(ValueError, err_msg):
|
||||||
|
sd.copy()
|
||||||
|
|
||||||
@requires_docstrings
|
@requires_docstrings
|
||||||
@requires_cdecimal
|
@requires_cdecimal
|
||||||
class SignatureTest(unittest.TestCase):
|
class SignatureTest(unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix crash when calling ``repr`` with a manually constructed SignalDict object.
|
||||||
|
Patch by Charlie Zhao.
|
|
@ -246,14 +246,12 @@ value_error_int(const char *mesg)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_32
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
value_error_ptr(const char *mesg)
|
value_error_ptr(const char *mesg)
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_ValueError, mesg);
|
PyErr_SetString(PyExc_ValueError, mesg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
type_error_int(const char *mesg)
|
type_error_int(const char *mesg)
|
||||||
|
@ -540,6 +538,8 @@ getround(PyObject *v)
|
||||||
initialized to new SignalDicts. Once a SignalDict is tied to
|
initialized to new SignalDicts. Once a SignalDict is tied to
|
||||||
a context, it cannot be deleted. */
|
a context, it cannot be deleted. */
|
||||||
|
|
||||||
|
static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict";
|
||||||
|
|
||||||
static int
|
static int
|
||||||
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
|
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
|
||||||
{
|
{
|
||||||
|
@ -548,8 +548,11 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Py_ssize_t
|
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;
|
return SIGNAL_MAP_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +560,9 @@ static PyObject *SignalTuple;
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signaldict_iter(PyObject *self UNUSED)
|
signaldict_iter(PyObject *self UNUSED)
|
||||||
{
|
{
|
||||||
|
if (SdFlagAddr(self) == NULL) {
|
||||||
|
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
return PyTuple_Type.tp_iter(SignalTuple);
|
return PyTuple_Type.tp_iter(SignalTuple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +570,9 @@ static PyObject *
|
||||||
signaldict_getitem(PyObject *self, PyObject *key)
|
signaldict_getitem(PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
|
if (SdFlagAddr(self) == NULL) {
|
||||||
|
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
flag = exception_as_flag(key);
|
flag = exception_as_flag(key);
|
||||||
if (flag & DEC_ERRORS) {
|
if (flag & DEC_ERRORS) {
|
||||||
|
@ -579,6 +588,10 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
if (SdFlagAddr(self) == NULL) {
|
||||||
|
return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
return value_error_int("signal keys cannot be deleted");
|
return value_error_int("signal keys cannot be deleted");
|
||||||
}
|
}
|
||||||
|
@ -611,6 +624,10 @@ signaldict_repr(PyObject *self)
|
||||||
const char *b[SIGNAL_MAP_LEN]; /* bool */
|
const char *b[SIGNAL_MAP_LEN]; /* bool */
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (SdFlagAddr(self) == NULL) {
|
||||||
|
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
assert(SIGNAL_MAP_LEN == 9);
|
assert(SIGNAL_MAP_LEN == 9);
|
||||||
|
|
||||||
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
|
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
|
||||||
|
@ -632,6 +649,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
|
||||||
PyObject *res = Py_NotImplemented;
|
PyObject *res = Py_NotImplemented;
|
||||||
|
|
||||||
assert(PyDecSignalDict_Check(v));
|
assert(PyDecSignalDict_Check(v));
|
||||||
|
if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) {
|
||||||
|
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
|
|
||||||
if (op == Py_EQ || op == Py_NE) {
|
if (op == Py_EQ || op == Py_NE) {
|
||||||
if (PyDecSignalDict_Check(w)) {
|
if (PyDecSignalDict_Check(w)) {
|
||||||
|
@ -660,6 +680,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
signaldict_copy(PyObject *self, PyObject *args UNUSED)
|
signaldict_copy(PyObject *self, PyObject *args UNUSED)
|
||||||
{
|
{
|
||||||
|
if (SdFlagAddr(self) == NULL) {
|
||||||
|
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
|
||||||
|
}
|
||||||
return flags_as_dict(SdFlags(self));
|
return flags_as_dict(SdFlags(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,7 @@ Modules/_decimal/_decimal.c - invalid_rounding_err -
|
||||||
Modules/_decimal/_decimal.c - invalid_signals_err -
|
Modules/_decimal/_decimal.c - invalid_signals_err -
|
||||||
Modules/_decimal/_decimal.c - signal_map -
|
Modules/_decimal/_decimal.c - signal_map -
|
||||||
Modules/_decimal/_decimal.c - ssize_constants -
|
Modules/_decimal/_decimal.c - ssize_constants -
|
||||||
|
Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG -
|
||||||
Modules/_elementtree.c - ExpatMemoryHandler -
|
Modules/_elementtree.c - ExpatMemoryHandler -
|
||||||
Modules/_hashopenssl.c - py_hashes -
|
Modules/_hashopenssl.c - py_hashes -
|
||||||
Modules/_hacl/Hacl_Hash_SHA1.c - _h0 -
|
Modules/_hacl/Hacl_Hash_SHA1.c - _h0 -
|
||||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Add table
Add a link
Reference in a new issue