@@ -513,6 +513,11 @@ multibytecodec_encode(const MultibyteCodec *codec,
513513 if (datalen == 0 && !(flags & MBENC_RESET ))
514514 return PyBytes_FromStringAndSize (NULL , 0 );
515515
516+ /* A callback may change a stateful encoder's errors attribute. */
517+ if (ERROR_ISCUSTOM (errors )) {
518+ Py_INCREF (errors );
519+ }
520+
516521 buf .excobj = NULL ;
517522 buf .outobj = NULL ;
518523 buf .inobj = text ; /* borrowed reference */
@@ -573,10 +578,12 @@ multibytecodec_encode(const MultibyteCodec *codec,
573578 if (inpos_t )
574579 * inpos_t = buf .inpos ;
575580 Py_XDECREF (buf .excobj );
581+ ERROR_DECREF (errors );
576582 return buf .outobj ;
577583
578584errorexit :
579585 Py_XDECREF (buf .excobj );
586+ ERROR_DECREF (errors );
580587 Py_XDECREF (buf .outobj );
581588 return NULL ;
582589}
@@ -1112,7 +1119,7 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
11121119 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
11131120 goto errorexit ;
11141121
1115- Py_DECREF ( codec ) ;
1122+ self -> codec_owner = codec ;
11161123 return (PyObject * )self ;
11171124
11181125errorexit :
@@ -1133,6 +1140,7 @@ mbiencoder_traverse(PyObject *op, visitproc visit, void *arg)
11331140 MultibyteIncrementalEncoderObject * self = _MultibyteIncrementalEncoderObject_CAST (op );
11341141 if (ERROR_ISCUSTOM (self -> errors ))
11351142 Py_VISIT (self -> errors );
1143+ Py_VISIT (self -> codec_owner );
11361144 return 0 ;
11371145}
11381146
@@ -1144,6 +1152,7 @@ mbiencoder_dealloc(PyObject *op)
11441152 PyObject_GC_UnTrack (self );
11451153 ERROR_DECREF (self -> errors );
11461154 Py_CLEAR (self -> pending );
1155+ Py_XDECREF (self -> codec_owner );
11471156 tp -> tp_free (self );
11481157 Py_DECREF (tp );
11491158}
@@ -1395,7 +1404,7 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
13951404 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
13961405 goto errorexit ;
13971406
1398- Py_DECREF ( codec ) ;
1407+ self -> codec_owner = codec ;
13991408 return (PyObject * )self ;
14001409
14011410errorexit :
@@ -1416,6 +1425,7 @@ mbidecoder_traverse(PyObject *op, visitproc visit, void *arg)
14161425 MultibyteIncrementalDecoderObject * self = _MultibyteIncrementalDecoderObject_CAST (op );
14171426 if (ERROR_ISCUSTOM (self -> errors ))
14181427 Py_VISIT (self -> errors );
1428+ Py_VISIT (self -> codec_owner );
14191429 return 0 ;
14201430}
14211431
@@ -1426,6 +1436,7 @@ mbidecoder_dealloc(PyObject *op)
14261436 PyTypeObject * tp = Py_TYPE (self );
14271437 PyObject_GC_UnTrack (self );
14281438 ERROR_DECREF (self -> errors );
1439+ Py_XDECREF (self -> codec_owner );
14291440 tp -> tp_free (self );
14301441 Py_DECREF (tp );
14311442}
@@ -1712,7 +1723,7 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17121723 self -> codec -> decinit (& self -> state , self -> codec ) != 0 )
17131724 goto errorexit ;
17141725
1715- Py_DECREF ( codec ) ;
1726+ self -> codec_owner = codec ;
17161727 return (PyObject * )self ;
17171728
17181729errorexit :
@@ -1734,6 +1745,7 @@ mbstreamreader_traverse(PyObject *op, visitproc visit, void *arg)
17341745 if (ERROR_ISCUSTOM (self -> errors ))
17351746 Py_VISIT (self -> errors );
17361747 Py_VISIT (self -> stream );
1748+ Py_VISIT (self -> codec_owner );
17371749 return 0 ;
17381750}
17391751
@@ -1745,6 +1757,7 @@ mbstreamreader_dealloc(PyObject *op)
17451757 PyObject_GC_UnTrack (self );
17461758 ERROR_DECREF (self -> errors );
17471759 Py_XDECREF (self -> stream );
1760+ Py_XDECREF (self -> codec_owner );
17481761 tp -> tp_free (self );
17491762 Py_DECREF (tp );
17501763}
@@ -1941,7 +1954,7 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
19411954 self -> codec -> encinit (& self -> state , self -> codec ) != 0 )
19421955 goto errorexit ;
19431956
1944- Py_DECREF ( codec ) ;
1957+ self -> codec_owner = codec ;
19451958 return (PyObject * )self ;
19461959
19471960errorexit :
@@ -1963,6 +1976,7 @@ mbstreamwriter_traverse(PyObject *op, visitproc visit, void *arg)
19631976 if (ERROR_ISCUSTOM (self -> errors ))
19641977 Py_VISIT (self -> errors );
19651978 Py_VISIT (self -> stream );
1979+ Py_VISIT (self -> codec_owner );
19661980 return 0 ;
19671981}
19681982
@@ -1974,6 +1988,7 @@ mbstreamwriter_dealloc(PyObject *op)
19741988 PyObject_GC_UnTrack (self );
19751989 ERROR_DECREF (self -> errors );
19761990 Py_XDECREF (self -> stream );
1991+ Py_XDECREF (self -> codec_owner );
19771992 tp -> tp_free (self );
19781993 Py_DECREF (tp );
19791994}
0 commit comments