@@ -2673,6 +2673,8 @@ SyntaxError_str(PySyntaxErrorObject *self)
26732673 if (!filename && !have_lineno )
26742674 return PyObject_Str (self -> msg ? self -> msg : Py_None );
26752675
2676+ // Even if 'filename' can be an instance of a subclass of 'str',
2677+ // we only render its "true" content and do not use str(filename).
26762678 if (filename && have_lineno )
26772679 result = PyUnicode_FromFormat ("%S (%U, line %ld)" ,
26782680 self -> msg ? self -> msg : Py_None ,
@@ -2790,29 +2792,47 @@ SimpleExtendsException(PyExc_ValueError, UnicodeError,
27902792
27912793/*
27922794 * Check the validity of 'attr' as a unicode or bytes object depending
2793- * on 'as_bytes' and return a new reference on it if it is the case .
2795+ * on 'as_bytes'.
27942796 *
27952797 * The 'name' is the attribute name and is only used for error reporting.
27962798 *
2797- * On success, this returns a strong reference on 'attr' .
2798- * On failure, this sets a TypeError and returns NULL .
2799+ * On success, this returns 0 .
2800+ * On failure, this sets a TypeError and returns -1 .
27992801 */
2800- static PyObject *
2801- as_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
2802+ static int
2803+ check_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
28022804{
28032805 assert (as_bytes == 0 || as_bytes == 1 );
28042806 if (attr == NULL ) {
2805- PyErr_Format (PyExc_TypeError , "%s attribute not set" , name );
2806- return NULL ;
2807+ PyErr_Format (PyExc_TypeError ,
2808+ "UnicodeError '%s' attribute is not set" ,
2809+ name );
2810+ return -1 ;
28072811 }
28082812 if (!(as_bytes ? PyBytes_Check (attr ) : PyUnicode_Check (attr ))) {
28092813 PyErr_Format (PyExc_TypeError ,
2810- "%s attribute must be %s" ,
2811- name ,
2812- as_bytes ? "bytes" : "unicode" );
2813- return NULL ;
2814+ "UnicodeError '%s' attribute must be a %s" ,
2815+ name , as_bytes ? "bytes" : "string" );
2816+ return -1 ;
28142817 }
2815- return Py_NewRef (attr );
2818+ return 0 ;
2819+ }
2820+
2821+
2822+ /*
2823+ * Check the validity of 'attr' as a unicode or bytes object depending
2824+ * on 'as_bytes' and return a new reference on it if it is the case.
2825+ *
2826+ * The 'name' is the attribute name and is only used for error reporting.
2827+ *
2828+ * On success, this returns a strong reference on 'attr'.
2829+ * On failure, this sets a TypeError and returns NULL.
2830+ */
2831+ static PyObject *
2832+ as_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
2833+ {
2834+ int rc = check_unicode_error_attribute (attr , name , as_bytes );
2835+ return rc < 0 ? NULL : Py_NewRef (attr );
28162836}
28172837
28182838
@@ -3379,7 +3399,10 @@ UnicodeEncodeError_str(PyObject *self)
33793399 if (encoding_str == NULL ) {
33803400 goto done ;
33813401 }
3382-
3402+ // calls to PyObject_Str(...) above might mutate 'exc->object'
3403+ if (check_unicode_error_attribute (exc -> object , "object" , false) < 0 ) {
3404+ goto done ;
3405+ }
33833406 Py_ssize_t len = PyUnicode_GET_LENGTH (exc -> object );
33843407 Py_ssize_t start = exc -> start , end = exc -> end ;
33853408
@@ -3499,7 +3522,10 @@ UnicodeDecodeError_str(PyObject *self)
34993522 if (encoding_str == NULL ) {
35003523 goto done ;
35013524 }
3502-
3525+ // calls to PyObject_Str(...) above might mutate 'exc->object'
3526+ if (check_unicode_error_attribute (exc -> object , "object" , true) < 0 ) {
3527+ goto done ;
3528+ }
35033529 Py_ssize_t len = PyBytes_GET_SIZE (exc -> object );
35043530 Py_ssize_t start = exc -> start , end = exc -> end ;
35053531
@@ -3595,7 +3621,10 @@ UnicodeTranslateError_str(PyObject *self)
35953621 if (reason_str == NULL ) {
35963622 goto done ;
35973623 }
3598-
3624+ // call to PyObject_Str(...) above might mutate 'exc->object'
3625+ if (check_unicode_error_attribute (exc -> object , "object" , false) < 0 ) {
3626+ goto done ;
3627+ }
35993628 Py_ssize_t len = PyUnicode_GET_LENGTH (exc -> object );
36003629 Py_ssize_t start = exc -> start , end = exc -> end ;
36013630
0 commit comments