@@ -514,6 +514,11 @@ multibytecodec_encode(const MultibyteCodec *codec,
514514 if (datalen == 0 && !(flags & MBENC_RESET ))
515515 return Py_GetConstant (Py_CONSTANT_EMPTY_BYTES );
516516
517+ /* A callback may change a stateful encoder's errors attribute. */
518+ if (ERROR_ISCUSTOM (errors )) {
519+ Py_INCREF (errors );
520+ }
521+
517522 buf .excobj = NULL ;
518523 buf .writer = NULL ;
519524 buf .inobj = text ; /* borrowed reference */
@@ -567,10 +572,12 @@ multibytecodec_encode(const MultibyteCodec *codec,
567572 if (inpos_t )
568573 * inpos_t = buf .inpos ;
569574 Py_XDECREF (buf .excobj );
575+ ERROR_DECREF (errors );
570576 return PyBytesWriter_FinishWithPointer (buf .writer , buf .outbuf );
571577
572578errorexit :
573579 Py_XDECREF (buf .excobj );
580+ ERROR_DECREF (errors );
574581 PyBytesWriter_Discard (buf .writer );
575582 return NULL ;
576583}
@@ -1101,7 +1108,7 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11011108 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
11021109 goto errorexit ;
11031110
1104- Py_DECREF ( codec ) ;
1111+ self -> codec_owner = codec ;
11051112 return (PyObject * )self ;
11061113
11071114errorexit :
@@ -1122,6 +1129,7 @@ mbiencoder_traverse(PyObject *op, visitproc visit, void *arg)
11221129 MultibyteIncrementalEncoderObject * self = _MultibyteIncrementalEncoderObject_CAST (op );
11231130 if (ERROR_ISCUSTOM (self -> errors ))
11241131 Py_VISIT (self -> errors );
1132+ Py_VISIT (self -> codec_owner );
11251133 return 0 ;
11261134}
11271135
@@ -1133,6 +1141,7 @@ mbiencoder_dealloc(PyObject *op)
11331141 PyObject_GC_UnTrack (self );
11341142 ERROR_DECREF (self -> errors );
11351143 Py_CLEAR (self -> pending );
1144+ Py_XDECREF (self -> codec_owner );
11361145 tp -> tp_free (self );
11371146 Py_DECREF (tp );
11381147}
@@ -1384,7 +1393,7 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
13841393 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
13851394 goto errorexit ;
13861395
1387- Py_DECREF ( codec ) ;
1396+ self -> codec_owner = codec ;
13881397 return (PyObject * )self ;
13891398
13901399errorexit :
@@ -1405,6 +1414,7 @@ mbidecoder_traverse(PyObject *op, visitproc visit, void *arg)
14051414 MultibyteIncrementalDecoderObject * self = _MultibyteIncrementalDecoderObject_CAST (op );
14061415 if (ERROR_ISCUSTOM (self -> errors ))
14071416 Py_VISIT (self -> errors );
1417+ Py_VISIT (self -> codec_owner );
14081418 return 0 ;
14091419}
14101420
@@ -1415,6 +1425,7 @@ mbidecoder_dealloc(PyObject *op)
14151425 PyTypeObject * tp = Py_TYPE (self );
14161426 PyObject_GC_UnTrack (self );
14171427 ERROR_DECREF (self -> errors );
1428+ Py_XDECREF (self -> codec_owner );
14181429 tp -> tp_free (self );
14191430 Py_DECREF (tp );
14201431}
@@ -1703,7 +1714,7 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17031714 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
17041715 goto errorexit ;
17051716
1706- Py_DECREF ( codec ) ;
1717+ self -> codec_owner = codec ;
17071718 return (PyObject * )self ;
17081719
17091720errorexit :
@@ -1725,6 +1736,7 @@ mbstreamreader_traverse(PyObject *op, visitproc visit, void *arg)
17251736 if (ERROR_ISCUSTOM (self -> errors ))
17261737 Py_VISIT (self -> errors );
17271738 Py_VISIT (self -> stream );
1739+ Py_VISIT (self -> codec_owner );
17281740 return 0 ;
17291741}
17301742
@@ -1736,6 +1748,7 @@ mbstreamreader_dealloc(PyObject *op)
17361748 PyObject_GC_UnTrack (self );
17371749 ERROR_DECREF (self -> errors );
17381750 Py_XDECREF (self -> stream );
1751+ Py_XDECREF (self -> codec_owner );
17391752 tp -> tp_free (self );
17401753 Py_DECREF (tp );
17411754}
@@ -1927,7 +1940,7 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19271940 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
19281941 goto errorexit ;
19291942
1930- Py_DECREF ( codec ) ;
1943+ self -> codec_owner = codec ;
19311944 return (PyObject * )self ;
19321945
19331946errorexit :
@@ -1949,6 +1962,7 @@ mbstreamwriter_traverse(PyObject *op, visitproc visit, void *arg)
19491962 if (ERROR_ISCUSTOM (self -> errors ))
19501963 Py_VISIT (self -> errors );
19511964 Py_VISIT (self -> stream );
1965+ Py_VISIT (self -> codec_owner );
19521966 return 0 ;
19531967}
19541968
@@ -1960,6 +1974,7 @@ mbstreamwriter_dealloc(PyObject *op)
19601974 PyObject_GC_UnTrack (self );
19611975 ERROR_DECREF (self -> errors );
19621976 Py_XDECREF (self -> stream );
1977+ Py_XDECREF (self -> codec_owner );
19631978 tp -> tp_free (self );
19641979 Py_DECREF (tp );
19651980}
0 commit comments