Skip to content

Commit 3eddfdf

Browse files
committed
gh-146152: Fix memory leak in _json encoder error paths
Remove objects from markers dict on all error paths in encoder_listencode_obj to prevent memory leaks when: - default() raises an exception - RecursionError occurs - Nested encoding fails Previously, objects were only removed on the success path, leaving strong references in the markers dict.
1 parent 91e1312 commit 3eddfdf

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a memory leak in the :mod:`json` module when encoding objects with a
2+
custom ``default()`` function that raises an exception, when a recursion
3+
error occurs, or when nested encoding fails.

Modules/_json.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,13 +1627,20 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer,
16271627
}
16281628
newobj = PyObject_CallOneArg(s->defaultfn, obj);
16291629
if (newobj == NULL) {
1630-
Py_XDECREF(ident);
1630+
if (ident != NULL) {
1631+
PyDict_DelItem(s->markers, ident);
1632+
Py_XDECREF(ident);
1633+
}
16311634
return -1;
16321635
}
16331636

16341637
if (_Py_EnterRecursiveCall(" while encoding a JSON object")) {
1638+
if (ident != NULL) {
1639+
PyDict_DelItem(s->markers, ident);
1640+
Py_XDECREF(ident);
1641+
}
16351642
Py_DECREF(newobj);
1636-
Py_XDECREF(ident);
1643+
16371644
return -1;
16381645
}
16391646
rv = encoder_listencode_obj(s, writer, newobj, indent_level, indent_cache);
@@ -1642,7 +1649,10 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer,
16421649
Py_DECREF(newobj);
16431650
if (rv) {
16441651
_PyErr_FormatNote("when serializing %T object", obj);
1645-
Py_XDECREF(ident);
1652+
if (ident != NULL) {
1653+
PyDict_DelItem(s->markers, ident);
1654+
Py_XDECREF(ident);
1655+
}
16461656
return -1;
16471657
}
16481658
if (ident != NULL) {

0 commit comments

Comments
 (0)