mirror of
https://github.com/python/cpython.git
synced 2026-06-27 19:36:07 +00:00
[3.15] gh-151814: Fix unbounded memory growth from repeated empty writes to io.TextIOWrapper (GH-151817)
(cherry picked from commit c61307222e)
Co-authored-by: Stan Ulbrych <stan@python.org>
This commit is contained in:
parent
bc52a01e71
commit
6bad84d64c
2 changed files with 28 additions and 20 deletions
|
|
@ -0,0 +1,2 @@
|
|||
Fix unbounded memory growth in :class:`io.TextIOWrapper` when repeatedly
|
||||
writing an empty string.
|
||||
|
|
@ -1755,32 +1755,38 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text)
|
|||
}
|
||||
}
|
||||
|
||||
if (self->pending_bytes == NULL) {
|
||||
assert(self->pending_bytes_count == 0);
|
||||
self->pending_bytes = b;
|
||||
}
|
||||
else if (!PyList_CheckExact(self->pending_bytes)) {
|
||||
PyObject *list = PyList_New(2);
|
||||
if (list == NULL) {
|
||||
Py_DECREF(b);
|
||||
return NULL;
|
||||
if (bytes_len > 0) {
|
||||
if (self->pending_bytes == NULL) {
|
||||
assert(self->pending_bytes_count == 0);
|
||||
self->pending_bytes = b;
|
||||
}
|
||||
// Since Python 3.12, allocating GC object won't trigger GC and release
|
||||
// GIL. See https://github.com/python/cpython/issues/97922
|
||||
assert(!PyList_CheckExact(self->pending_bytes));
|
||||
PyList_SET_ITEM(list, 0, self->pending_bytes);
|
||||
PyList_SET_ITEM(list, 1, b);
|
||||
self->pending_bytes = list;
|
||||
else if (!PyList_CheckExact(self->pending_bytes)) {
|
||||
PyObject *list = PyList_New(2);
|
||||
if (list == NULL) {
|
||||
Py_DECREF(b);
|
||||
return NULL;
|
||||
}
|
||||
// Since Python 3.12, allocating GC object won't trigger GC and release
|
||||
// GIL. See https://github.com/python/cpython/issues/97922
|
||||
assert(!PyList_CheckExact(self->pending_bytes));
|
||||
PyList_SET_ITEM(list, 0, self->pending_bytes);
|
||||
PyList_SET_ITEM(list, 1, b);
|
||||
self->pending_bytes = list;
|
||||
}
|
||||
else {
|
||||
if (PyList_Append(self->pending_bytes, b) < 0) {
|
||||
Py_DECREF(b);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(b);
|
||||
}
|
||||
|
||||
self->pending_bytes_count += bytes_len;
|
||||
}
|
||||
else {
|
||||
if (PyList_Append(self->pending_bytes, b) < 0) {
|
||||
Py_DECREF(b);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(b);
|
||||
}
|
||||
|
||||
self->pending_bytes_count += bytes_len;
|
||||
if (self->pending_bytes_count >= self->chunk_size || needflush ||
|
||||
text_needflush) {
|
||||
if (_textiowrapper_writeflush(self) < 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue