@@ -273,29 +273,35 @@ static compobject *
273273newcompobject (PyTypeObject * type )
274274{
275275 compobject * self ;
276- self = PyObject_New (compobject , type );
277- if (self == NULL )
276+ self = PyObject_GC_New (compobject , type );
277+ if (self == NULL ) {
278278 return NULL ;
279- self -> eof = 0 ;
280- self -> is_initialised = 0 ;
281- self -> zdict = NULL ;
279+ }
280+
281+ /* Initialize the remaining fields (untouched by PyObject_GC_New()). */
282+ const size_t offset = sizeof (struct { PyObject_HEAD });
283+ memset ((char * )self + offset , 0 , sizeof (* self ) - offset );
284+
282285 self -> unused_data = Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
283286 if (self -> unused_data == NULL ) {
284- Py_DECREF (self );
285- return NULL ;
287+ goto error ;
286288 }
287289 self -> unconsumed_tail = Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
288290 if (self -> unconsumed_tail == NULL ) {
289- Py_DECREF (self );
290- return NULL ;
291+ goto error ;
291292 }
292293 self -> lock = PyThread_allocate_lock ();
293294 if (self -> lock == NULL ) {
294- Py_DECREF (self );
295295 PyErr_SetString (PyExc_MemoryError , "Unable to allocate lock" );
296- return NULL ;
296+ goto error ;
297297 }
298+
299+ PyObject_GC_Track (self );
298300 return self ;
301+
302+ error :
303+ Py_DECREF (self );
304+ return NULL ;
299305}
300306
301307static void *
@@ -716,33 +722,41 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
716722}
717723
718724static void
719- Dealloc ( compobject * self )
725+ compobject_dealloc_impl ( PyObject * op , int ( * dealloc )( z_streamp ) )
720726{
721- PyTypeObject * type = Py_TYPE (self );
727+ PyTypeObject * type = Py_TYPE (op );
728+ PyObject_GC_UnTrack (op );
729+ compobject * self = _compobject_CAST (op );
730+ if (self -> is_initialised ) {
731+ (void )dealloc (& self -> zst );
732+ }
722733 PyThread_free_lock (self -> lock );
723734 Py_XDECREF (self -> unused_data );
724735 Py_XDECREF (self -> unconsumed_tail );
725736 Py_XDECREF (self -> zdict );
726- PyObject_Free (self );
737+ PyObject_GC_Del (self );
727738 Py_DECREF (type );
728739}
729740
741+ static int
742+ compobject_traverse (PyObject * op , visitproc visit , void * arg )
743+ {
744+ compobject * self = _compobject_CAST (op );
745+ Py_VISIT (Py_TYPE (op ));
746+ Py_VISIT (self -> zdict );
747+ return 0 ;
748+ }
749+
730750static void
731751Comp_dealloc (PyObject * op )
732752{
733- compobject * self = _compobject_CAST (op );
734- if (self -> is_initialised )
735- (void )deflateEnd (& self -> zst );
736- Dealloc (self );
753+ compobject_dealloc_impl (op , & deflateEnd );
737754}
738755
739756static void
740757Decomp_dealloc (PyObject * op )
741758{
742- compobject * self = _compobject_CAST (op );
743- if (self -> is_initialised )
744- (void )inflateEnd (& self -> zst );
745- Dealloc (self );
759+ compobject_dealloc_impl (op , & inflateEnd );
746760}
747761
748762/*[clinic input]
@@ -1115,6 +1129,7 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls)
11151129 return_value -> is_initialised = 1 ;
11161130
11171131 LEAVE_ZLIB (self );
1132+ assert (PyObject_GC_IsTracked ((PyObject * )return_value ));
11181133 return (PyObject * )return_value ;
11191134
11201135error :
@@ -1200,6 +1215,7 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls)
12001215 return_value -> is_initialised = 1 ;
12011216
12021217 LEAVE_ZLIB (self );
1218+ assert (PyObject_GC_IsTracked ((PyObject * )return_value ));
12031219 return (PyObject * )return_value ;
12041220
12051221error :
@@ -1368,6 +1384,8 @@ typedef struct {
13681384 char needs_input ;
13691385} ZlibDecompressor ;
13701386
1387+ #define ZlibDecompressor_CAST (op ) ((ZlibDecompressor *)(op))
1388+
13711389/*[clinic input]
13721390class zlib._ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType"
13731391[clinic start generated code]*/
@@ -1376,19 +1394,29 @@ class zlib._ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType"
13761394static void
13771395ZlibDecompressor_dealloc (PyObject * op )
13781396{
1379- ZlibDecompressor * self = (ZlibDecompressor * )op ;
1380- PyObject * type = (PyObject * )Py_TYPE (self );
1397+ PyTypeObject * type = Py_TYPE (op );
1398+ PyObject_GC_UnTrack (op );
1399+ ZlibDecompressor * self = ZlibDecompressor_CAST (op );
13811400 PyThread_free_lock (self -> lock );
13821401 if (self -> is_initialised ) {
13831402 inflateEnd (& self -> zst );
13841403 }
13851404 PyMem_Free (self -> input_buffer );
13861405 Py_CLEAR (self -> unused_data );
13871406 Py_CLEAR (self -> zdict );
1388- PyObject_Free (self );
1407+ PyObject_GC_Del (self );
13891408 Py_DECREF (type );
13901409}
13911410
1411+ static int
1412+ ZlibDecompressor_traverse (PyObject * op , visitproc visit , void * arg )
1413+ {
1414+ ZlibDecompressor * self = ZlibDecompressor_CAST (op );
1415+ Py_VISIT (Py_TYPE (op ));
1416+ Py_VISIT (self -> zdict );
1417+ return 0 ;
1418+ }
1419+
13921420static int
13931421set_inflate_zdict_ZlibDecompressor (zlibstate * state , ZlibDecompressor * self )
13941422{
@@ -1732,57 +1760,59 @@ zlib__ZlibDecompressor_impl(PyTypeObject *type, int wbits, PyObject *zdict)
17321760/*[clinic end generated code: output=1065607df0d33baa input=9ebad0be6de226e2]*/
17331761{
17341762 zlibstate * state = PyType_GetModuleState (type );
1735- ZlibDecompressor * self = PyObject_New (ZlibDecompressor , type );
1763+ ZlibDecompressor * self = PyObject_GC_New (ZlibDecompressor , type );
17361764 if (self == NULL ) {
17371765 return NULL ;
17381766 }
1739- self -> eof = 0 ;
1767+
1768+ /* Initialize the remaining fields (untouched by PyObject_GC_New()). */
1769+ const size_t offset = sizeof (struct { PyObject_HEAD });
1770+ memset ((char * )self + offset , 0 , sizeof (* self ) - offset );
1771+
17401772 self -> needs_input = 1 ;
1741- self -> avail_in_real = 0 ;
1742- self -> input_buffer = NULL ;
1743- self -> input_buffer_size = 0 ;
17441773 self -> zdict = Py_XNewRef (zdict );
1774+
17451775 self -> zst .opaque = NULL ;
17461776 self -> zst .zalloc = PyZlib_Malloc ;
17471777 self -> zst .zfree = PyZlib_Free ;
1748- self -> zst .next_in = NULL ;
1749- self -> zst .avail_in = 0 ;
1778+
17501779 self -> unused_data = PyBytes_FromStringAndSize (NULL , 0 );
17511780 if (self -> unused_data == NULL ) {
1752- Py_CLEAR (self );
1753- return NULL ;
1781+ goto error ;
17541782 }
17551783 self -> lock = PyThread_allocate_lock ();
17561784 if (self -> lock == NULL ) {
1757- Py_DECREF (self );
17581785 PyErr_SetString (PyExc_MemoryError , "Unable to allocate lock" );
1759- return NULL ;
1786+ goto error ;
17601787 }
17611788 int err = inflateInit2 (& (self -> zst ), wbits );
17621789 switch (err ) {
17631790 case Z_OK :
17641791 self -> is_initialised = 1 ;
17651792 if (self -> zdict != NULL && wbits < 0 ) {
17661793 if (set_inflate_zdict_ZlibDecompressor (state , self ) < 0 ) {
1767- Py_DECREF (self );
1768- return NULL ;
1794+ goto error ;
17691795 }
17701796 }
1771- return ( PyObject * ) self ;
1797+ break ;
17721798 case Z_STREAM_ERROR :
1773- Py_DECREF (self );
17741799 PyErr_SetString (PyExc_ValueError , "Invalid initialization option" );
1775- return NULL ;
1800+ goto error ;
17761801 case Z_MEM_ERROR :
1777- Py_DECREF (self );
17781802 PyErr_SetString (PyExc_MemoryError ,
17791803 "Can't allocate memory for decompression object" );
1780- return NULL ;
1804+ goto error ;
17811805 default :
17821806 zlib_error (state , self -> zst , err , "while creating decompression object" );
1783- Py_DECREF (self );
1784- return NULL ;
1807+ goto error ;
17851808 }
1809+
1810+ PyObject_GC_Track (self );
1811+ return (PyObject * )self ;
1812+
1813+ error :
1814+ Py_DECREF (self );
1815+ return NULL ;
17861816}
17871817
17881818#include "clinic/zlibmodule.c.h"
@@ -2015,19 +2045,25 @@ static PyMethodDef zlib_methods[] =
20152045
20162046static PyType_Slot Comptype_slots [] = {
20172047 {Py_tp_dealloc , Comp_dealloc },
2048+ {Py_tp_traverse , compobject_traverse },
20182049 {Py_tp_methods , comp_methods },
20192050 {0 , 0 },
20202051};
20212052
20222053static PyType_Spec Comptype_spec = {
20232054 .name = "zlib.Compress" ,
20242055 .basicsize = sizeof (compobject ),
2025- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
2056+ .flags = (
2057+ Py_TPFLAGS_DEFAULT
2058+ | Py_TPFLAGS_DISALLOW_INSTANTIATION
2059+ | Py_TPFLAGS_HAVE_GC
2060+ ),
20262061 .slots = Comptype_slots ,
20272062};
20282063
20292064static PyType_Slot Decomptype_slots [] = {
20302065 {Py_tp_dealloc , Decomp_dealloc },
2066+ {Py_tp_traverse , compobject_traverse },
20312067 {Py_tp_methods , Decomp_methods },
20322068 {Py_tp_members , Decomp_members },
20332069 {0 , 0 },
@@ -2036,12 +2072,17 @@ static PyType_Slot Decomptype_slots[] = {
20362072static PyType_Spec Decomptype_spec = {
20372073 .name = "zlib.Decompress" ,
20382074 .basicsize = sizeof (compobject ),
2039- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION ,
2075+ .flags = (
2076+ Py_TPFLAGS_DEFAULT
2077+ | Py_TPFLAGS_DISALLOW_INSTANTIATION
2078+ | Py_TPFLAGS_HAVE_GC
2079+ ),
20402080 .slots = Decomptype_slots ,
20412081};
20422082
20432083static PyType_Slot ZlibDecompressor_type_slots [] = {
20442084 {Py_tp_dealloc , ZlibDecompressor_dealloc },
2085+ {Py_tp_traverse , ZlibDecompressor_traverse },
20452086 {Py_tp_members , ZlibDecompressor_members },
20462087 {Py_tp_new , zlib__ZlibDecompressor },
20472088 {Py_tp_doc , (char * )zlib__ZlibDecompressor__doc__ },
@@ -2056,7 +2097,11 @@ static PyType_Spec ZlibDecompressor_type_spec = {
20562097 // ZlibDecompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag
20572098 // which prevents to create a subclass.
20582099 // So calling PyType_GetModuleState() in this file is always safe.
2059- .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE ),
2100+ .flags = (
2101+ Py_TPFLAGS_DEFAULT
2102+ | Py_TPFLAGS_IMMUTABLETYPE
2103+ | Py_TPFLAGS_HAVE_GC
2104+ ),
20602105 .slots = ZlibDecompressor_type_slots ,
20612106};
20622107
0 commit comments