From 52b0888dbdf58be4b7cd34717e2fcc7079c93aca Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 3 Nov 2016 15:36:50 +0200 Subject: Issue #28387: Fixed possible crash in _io.TextIOWrapper deallocator when the garbage collector is invoked in other thread. Based on patch by Sebastian Cufre. --- Misc/ACKS | 1 + Misc/NEWS | 4 ++++ Modules/_io/textio.c | 15 +++++++-------- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS index bec9a42..06de9e8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -296,6 +296,7 @@ Simon Cross Felipe Cruz Drew Csillag Joaquin Cuenca Abela +Sebastian Cufre John Cugini Tom Culliton Antonio Cuni diff --git a/Misc/NEWS b/Misc/NEWS index a296d6a..34e45cd 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -60,6 +60,10 @@ Core and Builtins Library ------- +- Issue #28387: Fixed possible crash in _io.TextIOWrapper deallocator when + the garbage collector is invoked in other thread. Based on patch by + Sebastian Cufre. + - Issue #28449: tarfile.open() with mode "r" or "r:" now tries to open a tar file with compression before trying to open it without compression. Otherwise it had 50% chance failed with ignore_zeros=True. diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index a95edce..b4007c2 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -1071,11 +1071,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) return -1; } -static int +static void _textiowrapper_clear(textio *self) { - if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) - return -1; self->ok = 0; Py_CLEAR(self->buffer); Py_CLEAR(self->encoding); @@ -1087,18 +1085,19 @@ _textiowrapper_clear(textio *self) Py_CLEAR(self->snapshot); Py_CLEAR(self->errors); Py_CLEAR(self->raw); - return 0; + + Py_CLEAR(self->dict); } static void textiowrapper_dealloc(textio *self) { - if (_textiowrapper_clear(self) < 0) + if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) return; _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->dict); + _textiowrapper_clear(self); Py_TYPE(self)->tp_free((PyObject *)self); } @@ -1123,9 +1122,9 @@ textiowrapper_traverse(textio *self, visitproc visit, void *arg) static int textiowrapper_clear(textio *self) { - if (_textiowrapper_clear(self) < 0) + if (self->ok && _PyIOBase_finalize((PyObject *) self) < 0) return -1; - Py_CLEAR(self->dict); + _textiowrapper_clear(self); return 0; } -- cgit v0.12