@@ -2784,6 +2784,8 @@ SyntaxError_str(PyObject *op)
27842784 if (!filename && !have_lineno )
27852785 return PyObject_Str (self -> msg ? self -> msg : Py_None );
27862786
2787+ // Even if 'filename' can be an instance of a subclass of 'str',
2788+ // we only render its "true" content and do not use str(filename).
27872789 if (filename && have_lineno )
27882790 result = PyUnicode_FromFormat ("%S (%U, line %ld)" ,
27892791 self -> msg ? self -> msg : Py_None ,
@@ -2903,29 +2905,47 @@ SimpleExtendsException(PyExc_ValueError, UnicodeError,
29032905
29042906/*
29052907 * Check the validity of 'attr' as a unicode or bytes object depending
2906- * on 'as_bytes' and return a new reference on it if it is the case .
2908+ * on 'as_bytes'.
29072909 *
29082910 * The 'name' is the attribute name and is only used for error reporting.
29092911 *
2910- * On success, this returns a strong reference on 'attr' .
2911- * On failure, this sets a TypeError and returns NULL .
2912+ * On success, this returns 0 .
2913+ * On failure, this sets a TypeError and returns -1 .
29122914 */
2913- static PyObject *
2914- as_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
2915+ static int
2916+ check_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
29152917{
29162918 assert (as_bytes == 0 || as_bytes == 1 );
29172919 if (attr == NULL ) {
2918- PyErr_Format (PyExc_TypeError , "%s attribute not set" , name );
2919- return NULL ;
2920+ PyErr_Format (PyExc_TypeError ,
2921+ "UnicodeError '%s' attribute is not set" ,
2922+ name );
2923+ return -1 ;
29202924 }
29212925 if (!(as_bytes ? PyBytes_Check (attr ) : PyUnicode_Check (attr ))) {
29222926 PyErr_Format (PyExc_TypeError ,
2923- "%s attribute must be %s" ,
2924- name ,
2925- as_bytes ? "bytes" : "unicode" );
2926- return NULL ;
2927+ "UnicodeError '%s' attribute must be a %s" ,
2928+ name , as_bytes ? "bytes" : "string" );
2929+ return -1 ;
29272930 }
2928- return Py_NewRef (attr );
2931+ return 0 ;
2932+ }
2933+
2934+
2935+ /*
2936+ * Check the validity of 'attr' as a unicode or bytes object depending
2937+ * on 'as_bytes' and return a new reference on it if it is the case.
2938+ *
2939+ * The 'name' is the attribute name and is only used for error reporting.
2940+ *
2941+ * On success, this returns a strong reference on 'attr'.
2942+ * On failure, this sets a TypeError and returns NULL.
2943+ */
2944+ static PyObject *
2945+ as_unicode_error_attribute (PyObject * attr , const char * name , int as_bytes )
2946+ {
2947+ int rc = check_unicode_error_attribute (attr , name , as_bytes );
2948+ return rc < 0 ? NULL : Py_NewRef (attr );
29292949}
29302950
29312951
@@ -3591,7 +3611,10 @@ UnicodeEncodeError_str(PyObject *self)
35913611 if (encoding_str == NULL ) {
35923612 goto done ;
35933613 }
3594-
3614+ // calls to PyObject_Str(...) above might mutate 'exc->object'
3615+ if (check_unicode_error_attribute (exc -> object , "object" , false) < 0 ) {
3616+ goto done ;
3617+ }
35953618 Py_ssize_t len = PyUnicode_GET_LENGTH (exc -> object );
35963619 Py_ssize_t start = exc -> start , end = exc -> end ;
35973620
@@ -3711,7 +3734,10 @@ UnicodeDecodeError_str(PyObject *self)
37113734 if (encoding_str == NULL ) {
37123735 goto done ;
37133736 }
3714-
3737+ // calls to PyObject_Str(...) above might mutate 'exc->object'
3738+ if (check_unicode_error_attribute (exc -> object , "object" , true) < 0 ) {
3739+ goto done ;
3740+ }
37153741 Py_ssize_t len = PyBytes_GET_SIZE (exc -> object );
37163742 Py_ssize_t start = exc -> start , end = exc -> end ;
37173743
@@ -3807,7 +3833,10 @@ UnicodeTranslateError_str(PyObject *self)
38073833 if (reason_str == NULL ) {
38083834 goto done ;
38093835 }
3810-
3836+ // call to PyObject_Str(...) above might mutate 'exc->object'
3837+ if (check_unicode_error_attribute (exc -> object , "object" , false) < 0 ) {
3838+ goto done ;
3839+ }
38113840 Py_ssize_t len = PyUnicode_GET_LENGTH (exc -> object );
38123841 Py_ssize_t start = exc -> start , end = exc -> end ;
38133842
0 commit comments