@@ -521,6 +521,11 @@ multibytecodec_encode(const MultibyteCodec *codec,
521521 if (datalen == 0 && !(flags & MBENC_RESET ))
522522 return PyBytes_FromStringAndSize (NULL , 0 );
523523
524+ /* A callback may change a stateful encoder's errors attribute. */
525+ if (ERROR_ISCUSTOM (errors )) {
526+ Py_INCREF (errors );
527+ }
528+
524529 buf .excobj = NULL ;
525530 buf .outobj = NULL ;
526531 buf .inobj = text ; /* borrowed reference */
@@ -581,10 +586,12 @@ multibytecodec_encode(const MultibyteCodec *codec,
581586 if (inpos_t )
582587 * inpos_t = buf .inpos ;
583588 Py_XDECREF (buf .excobj );
589+ ERROR_DECREF (errors );
584590 return buf .outobj ;
585591
586592errorexit :
587593 Py_XDECREF (buf .excobj );
594+ ERROR_DECREF (errors );
588595 Py_XDECREF (buf .outobj );
589596 return NULL ;
590597}
@@ -1120,7 +1127,7 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11201127 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
11211128 goto errorexit ;
11221129
1123- Py_DECREF ( codec ) ;
1130+ self -> codec_owner = codec ;
11241131 return (PyObject * )self ;
11251132
11261133errorexit :
@@ -1141,6 +1148,7 @@ mbiencoder_traverse(PyObject *op, visitproc visit, void *arg)
11411148 MultibyteIncrementalEncoderObject * self = _MultibyteIncrementalEncoderObject_CAST (op );
11421149 if (ERROR_ISCUSTOM (self -> errors ))
11431150 Py_VISIT (self -> errors );
1151+ Py_VISIT (self -> codec_owner );
11441152 return 0 ;
11451153}
11461154
@@ -1152,6 +1160,7 @@ mbiencoder_dealloc(PyObject *op)
11521160 PyObject_GC_UnTrack (self );
11531161 ERROR_DECREF (self -> errors );
11541162 Py_CLEAR (self -> pending );
1163+ Py_XDECREF (self -> codec_owner );
11551164 tp -> tp_free (self );
11561165 Py_DECREF (tp );
11571166}
@@ -1403,7 +1412,7 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
14031412 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
14041413 goto errorexit ;
14051414
1406- Py_DECREF ( codec ) ;
1415+ self -> codec_owner = codec ;
14071416 return (PyObject * )self ;
14081417
14091418errorexit :
@@ -1424,6 +1433,7 @@ mbidecoder_traverse(PyObject *op, visitproc visit, void *arg)
14241433 MultibyteIncrementalDecoderObject * self = _MultibyteIncrementalDecoderObject_CAST (op );
14251434 if (ERROR_ISCUSTOM (self -> errors ))
14261435 Py_VISIT (self -> errors );
1436+ Py_VISIT (self -> codec_owner );
14271437 return 0 ;
14281438}
14291439
@@ -1434,6 +1444,7 @@ mbidecoder_dealloc(PyObject *op)
14341444 PyTypeObject * tp = Py_TYPE (self );
14351445 PyObject_GC_UnTrack (self );
14361446 ERROR_DECREF (self -> errors );
1447+ Py_XDECREF (self -> codec_owner );
14371448 tp -> tp_free (self );
14381449 Py_DECREF (tp );
14391450}
@@ -1720,7 +1731,7 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17201731 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
17211732 goto errorexit ;
17221733
1723- Py_DECREF ( codec ) ;
1734+ self -> codec_owner = codec ;
17241735 return (PyObject * )self ;
17251736
17261737errorexit :
@@ -1742,6 +1753,7 @@ mbstreamreader_traverse(PyObject *op, visitproc visit, void *arg)
17421753 if (ERROR_ISCUSTOM (self -> errors ))
17431754 Py_VISIT (self -> errors );
17441755 Py_VISIT (self -> stream );
1756+ Py_VISIT (self -> codec_owner );
17451757 return 0 ;
17461758}
17471759
@@ -1753,6 +1765,7 @@ mbstreamreader_dealloc(PyObject *op)
17531765 PyObject_GC_UnTrack (self );
17541766 ERROR_DECREF (self -> errors );
17551767 Py_XDECREF (self -> stream );
1768+ Py_XDECREF (self -> codec_owner );
17561769 tp -> tp_free (self );
17571770 Py_DECREF (tp );
17581771}
@@ -1949,7 +1962,7 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19491962 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
19501963 goto errorexit ;
19511964
1952- Py_DECREF ( codec ) ;
1965+ self -> codec_owner = codec ;
19531966 return (PyObject * )self ;
19541967
19551968errorexit :
@@ -1971,6 +1984,7 @@ mbstreamwriter_traverse(PyObject *op, visitproc visit, void *arg)
19711984 if (ERROR_ISCUSTOM (self -> errors ))
19721985 Py_VISIT (self -> errors );
19731986 Py_VISIT (self -> stream );
1987+ Py_VISIT (self -> codec_owner );
19741988 return 0 ;
19751989}
19761990
@@ -1982,6 +1996,7 @@ mbstreamwriter_dealloc(PyObject *op)
19821996 PyObject_GC_UnTrack (self );
19831997 ERROR_DECREF (self -> errors );
19841998 Py_XDECREF (self -> stream );
1999+ Py_XDECREF (self -> codec_owner );
19852000 tp -> tp_free (self );
19862001 Py_DECREF (tp );
19872002}
0 commit comments