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_cdecimal
class SignatureTest(unittest.TestCase):
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)
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)
{
}
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 UNUSED)
{
+ if (SdFlagAddr(self) == NULL) {
+ return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
+ }
return PyTuple_Type.tp_iter(SignalTuple);
}
signaldict_getitem(PyObject *self, PyObject *key)
{
uint32_t flag;
+ if (SdFlagAddr(self) == NULL) {
+ return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
+ }
flag = exception_as_flag(key);
if (flag & DEC_ERRORS) {
uint32_t flag;
int x;
+ if (SdFlagAddr(self) == NULL) {
+ return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
+ }
+
if (value == NULL) {
return value_error_int("signal keys cannot be deleted");
}
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);
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
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 (PyDecSignalDict_Check(w)) {
res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
static PyObject *
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));
}