Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a15d06c

Browse filesBrowse files
[3.11] gh-106263: Fix segfault in signaldict_repr in _decimal module (#… (#107490)
Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com> (cherry picked from commit 3979150)
1 parent 81d0c7c commit a15d06c
Copy full SHA for a15d06c

File tree

Expand file treeCollapse file tree

4 files changed

+60
-3
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+60
-3
lines changed

‎Lib/test/test_decimal.py

Copy file name to clipboardExpand all lines: Lib/test/test_decimal.py
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5682,6 +5682,36 @@ def test_maxcontext_exact_arith(self):
56825682
self.assertEqual(Decimal(400) ** -1, Decimal('0.0025'))
56835683

56845684

5685+
def test_c_signaldict_segfault(self):
5686+
# See gh-106263 for details.
5687+
SignalDict = type(C.Context().flags)
5688+
sd = SignalDict()
5689+
err_msg = "invalid signal dict"
5690+
5691+
with self.assertRaisesRegex(ValueError, err_msg):
5692+
len(sd)
5693+
5694+
with self.assertRaisesRegex(ValueError, err_msg):
5695+
iter(sd)
5696+
5697+
with self.assertRaisesRegex(ValueError, err_msg):
5698+
repr(sd)
5699+
5700+
with self.assertRaisesRegex(ValueError, err_msg):
5701+
sd[C.InvalidOperation] = True
5702+
5703+
with self.assertRaisesRegex(ValueError, err_msg):
5704+
sd[C.InvalidOperation]
5705+
5706+
with self.assertRaisesRegex(ValueError, err_msg):
5707+
sd == C.Context().flags
5708+
5709+
with self.assertRaisesRegex(ValueError, err_msg):
5710+
C.Context().flags == sd
5711+
5712+
with self.assertRaisesRegex(ValueError, err_msg):
5713+
sd.copy()
5714+
56855715
@requires_docstrings
56865716
@requires_cdecimal
56875717
class SignatureTest(unittest.TestCase):
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when calling ``repr`` with a manually constructed SignalDict object.
2+
Patch by Charlie Zhao.

‎Modules/_decimal/_decimal.c

Copy file name to clipboardExpand all lines: Modules/_decimal/_decimal.c
+27-3Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,14 +247,12 @@ value_error_int(const char *mesg)
247247
return -1;
248248
}
249249

250-
#ifdef CONFIG_32
251250
static PyObject *
252251
value_error_ptr(const char *mesg)
253252
{
254253
PyErr_SetString(PyExc_ValueError, mesg);
255254
return NULL;
256255
}
257-
#endif
258256

259257
static int
260258
type_error_int(const char *mesg)
@@ -541,6 +539,8 @@ getround(PyObject *v)
541539
initialized to new SignalDicts. Once a SignalDict is tied to
542540
a context, it cannot be deleted. */
543541

542+
static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict";
543+
544544
static int
545545
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
546546
{
@@ -549,22 +549,31 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
549549
}
550550

551551
static Py_ssize_t
552-
signaldict_len(PyObject *self UNUSED)
552+
signaldict_len(PyObject *self)
553553
{
554+
if (SdFlagAddr(self) == NULL) {
555+
return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
556+
}
554557
return SIGNAL_MAP_LEN;
555558
}
556559

557560
static PyObject *SignalTuple;
558561
static PyObject *
559562
signaldict_iter(PyObject *self UNUSED)
560563
{
564+
if (SdFlagAddr(self) == NULL) {
565+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
566+
}
561567
return PyTuple_Type.tp_iter(SignalTuple);
562568
}
563569

564570
static PyObject *
565571
signaldict_getitem(PyObject *self, PyObject *key)
566572
{
567573
uint32_t flag;
574+
if (SdFlagAddr(self) == NULL) {
575+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
576+
}
568577

569578
flag = exception_as_flag(key);
570579
if (flag & DEC_ERRORS) {
@@ -580,6 +589,10 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
580589
uint32_t flag;
581590
int x;
582591

592+
if (SdFlagAddr(self) == NULL) {
593+
return value_error_int(INVALID_SIGNALDICT_ERROR_MSG);
594+
}
595+
583596
if (value == NULL) {
584597
return value_error_int("signal keys cannot be deleted");
585598
}
@@ -612,6 +625,10 @@ signaldict_repr(PyObject *self)
612625
const char *b[SIGNAL_MAP_LEN]; /* bool */
613626
int i;
614627

628+
if (SdFlagAddr(self) == NULL) {
629+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
630+
}
631+
615632
assert(SIGNAL_MAP_LEN == 9);
616633

617634
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
@@ -634,6 +651,10 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
634651

635652
assert(PyDecSignalDict_Check(v));
636653

654+
if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) {
655+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
656+
}
657+
637658
if (op == Py_EQ || op == Py_NE) {
638659
if (PyDecSignalDict_Check(w)) {
639660
res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
@@ -662,6 +683,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op)
662683
static PyObject *
663684
signaldict_copy(PyObject *self, PyObject *args UNUSED)
664685
{
686+
if (SdFlagAddr(self) == NULL) {
687+
return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG);
688+
}
665689
return flags_as_dict(SdFlags(self));
666690
}
667691

‎Tools/c-analyzer/cpython/ignored.tsv

Copy file name to clipboardExpand all lines: Tools/c-analyzer/cpython/ignored.tsv
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,7 @@ Modules/_decimal/_decimal.c - invalid_rounding_err -
14321432
Modules/_decimal/_decimal.c - invalid_signals_err -
14331433
Modules/_decimal/_decimal.c - signal_map -
14341434
Modules/_decimal/_decimal.c - ssize_constants -
1435+
Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG -
14351436
Modules/_elementtree.c - ExpatMemoryHandler -
14361437
Modules/_io/_iomodule.c - static_types -
14371438
Modules/_io/textio.c - encodefuncs -

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.