-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
gh-146152: Fix memory leak in _json encoder error paths #146164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0597100
9ec9348
cd9cc6f
5428b5e
b68b52b
cafe9ba
a4be61f
f7bdb6f
f09ce9a
5359ecd
753a88e
6498f26
6b69fea
81332c7
a9c895e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Fix a memory leak in the :mod:`json` module when a RecursionError occurs | ||
| during encoding. Previously, objects created in the ``default()`` function | ||
| while recursively encoding JSON could remain alive due to being tracked | ||
| indefinitely in the encoder's internal circular-reference dictionary. This | ||
| change ensures such objects are properly freed after the exception. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1632,8 +1632,11 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (_Py_EnterRecursiveCall(" while encoding a JSON object")) { | ||||||||||||||||||||||||||
| Py_DECREF(newobj); | ||||||||||||||||||||||||||
| if (ident != NULL) { | ||||||||||||||||||||||||||
| (void)PyDict_DelItem(s->markers, ident); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+1635
to
+1637
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Actually since we are anyway falling through the return -1 case we can simplify this as follows. Then keep the XDECREF for indent. However explicitly suppress the error code of DelItem. |
||||||||||||||||||||||||||
| Py_XDECREF(ident); | ||||||||||||||||||||||||||
| Py_DECREF(newobj); | ||||||||||||||||||||||||||
| return -1; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| rv = encoder_listencode_obj(s, writer, newobj, indent_level, indent_cache); | ||||||||||||||||||||||||||
|
|
@@ -1642,12 +1645,15 @@ encoder_listencode_obj(PyEncoderObject *s, PyUnicodeWriter *writer, | |||||||||||||||||||||||||
| Py_DECREF(newobj); | ||||||||||||||||||||||||||
| if (rv) { | ||||||||||||||||||||||||||
| _PyErr_FormatNote("when serializing %T object", obj); | ||||||||||||||||||||||||||
okiemute04 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
| if (ident != NULL) { | ||||||||||||||||||||||||||
| (void)PyDict_DelItem(s->markers, ident); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
Comment on lines
+1648
to
+1650
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one can benefit from the same optimization as my other comment as we anyway return -1. |
||||||||||||||||||||||||||
| Py_XDECREF(ident); | ||||||||||||||||||||||||||
| return -1; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| if (ident != NULL) { | ||||||||||||||||||||||||||
| if (PyDict_DelItem(s->markers, ident)) { | ||||||||||||||||||||||||||
| Py_XDECREF(ident); | ||||||||||||||||||||||||||
| Py_DECREF(ident); | ||||||||||||||||||||||||||
| return -1; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| Py_XDECREF(ident); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave this blank line.