Skip to content

Commit a65fe07

Browse files
[3.13] gh-123243: Fix reference leak in _decimal (GH-123244) (#123280)
gh-123243: Fix reference leak in `_decimal` (GH-123244) (cherry picked from commit 5ff638f) Co-authored-by: neonene <[email protected]>
1 parent 935b8b4 commit a65fe07

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix memory leak in :mod:`!_decimal`.

Modules/_decimal/_decimal.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,10 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
13901390
CtxCaps(self) = 1;
13911391
self->tstate = NULL;
13921392

1393+
if (type == state->PyDecContext_Type) {
1394+
PyObject_GC_Track(self);
1395+
}
1396+
assert(PyObject_GC_IsTracked((PyObject *)self));
13931397
return (PyObject *)self;
13941398
}
13951399

@@ -2038,6 +2042,10 @@ PyDecType_New(PyTypeObject *type)
20382042
MPD(dec)->alloc = _Py_DEC_MINALLOC;
20392043
MPD(dec)->data = dec->data;
20402044

2045+
if (type == state->PyDec_Type) {
2046+
PyObject_GC_Track(dec);
2047+
}
2048+
assert(PyObject_GC_IsTracked((PyObject *)dec));
20412049
return (PyObject *)dec;
20422050
}
20432051
#define dec_alloc(st) PyDecType_New((st)->PyDec_Type)
@@ -6143,8 +6151,22 @@ decimal_clear(PyObject *module)
61436151
Py_CLEAR(state->SignalTuple);
61446152
Py_CLEAR(state->PyDecimal);
61456153

6146-
PyMem_Free(state->signal_map);
6147-
PyMem_Free(state->cond_map);
6154+
if (state->signal_map != NULL) {
6155+
for (DecCondMap *cm = state->signal_map; cm->name != NULL; cm++) {
6156+
Py_DECREF(cm->ex);
6157+
}
6158+
PyMem_Free(state->signal_map);
6159+
state->signal_map = NULL;
6160+
}
6161+
6162+
if (state->cond_map != NULL) {
6163+
// cond_map[0].ex has borrowed a reference from signal_map[0].ex
6164+
for (DecCondMap *cm = state->cond_map + 1; cm->name != NULL; cm++) {
6165+
Py_DECREF(cm->ex);
6166+
}
6167+
PyMem_Free(state->cond_map);
6168+
state->cond_map = NULL;
6169+
}
61486170
return 0;
61496171
}
61506172

0 commit comments

Comments
 (0)