@@ -4113,8 +4113,34 @@ decode_utf8(struct compiling *c, const char **sPtr, const char *end)
41134113 return PyUnicode_DecodeUTF8 (t , s - t , NULL );
41144114}
41154115
4116+ static int
4117+ warn_invalid_escape_sequence (struct compiling * c , const node * n ,
4118+ char first_invalid_escape_char )
4119+ {
4120+ PyObject * msg = PyUnicode_FromFormat ("invalid escape sequence \\%c" ,
4121+ first_invalid_escape_char );
4122+ if (msg == NULL ) {
4123+ return -1 ;
4124+ }
4125+ if (PyErr_WarnExplicitObject (PyExc_DeprecationWarning , msg ,
4126+ c -> c_filename , LINENO (n ),
4127+ NULL , NULL ) < 0 &&
4128+ PyErr_ExceptionMatches (PyExc_DeprecationWarning ))
4129+ {
4130+ const char * s = PyUnicode_AsUTF8 (msg );
4131+ if (s != NULL ) {
4132+ ast_error (c , n , s );
4133+ }
4134+ Py_DECREF (msg );
4135+ return -1 ;
4136+ }
4137+ Py_DECREF (msg );
4138+ return 0 ;
4139+ }
4140+
41164141static PyObject *
4117- decode_unicode_with_escapes (struct compiling * c , const char * s , size_t len )
4142+ decode_unicode_with_escapes (struct compiling * c , const node * n , const char * s ,
4143+ size_t len )
41184144{
41194145 PyObject * v , * u ;
41204146 char * buf ;
@@ -4167,11 +4193,41 @@ decode_unicode_with_escapes(struct compiling *c, const char *s, size_t len)
41674193 len = p - buf ;
41684194 s = buf ;
41694195
4170- v = PyUnicode_DecodeUnicodeEscape (s , len , NULL );
4196+ const char * first_invalid_escape ;
4197+ v = _PyUnicode_DecodeUnicodeEscape (s , len , NULL , & first_invalid_escape );
4198+
4199+ if (v != NULL && first_invalid_escape != NULL ) {
4200+ if (warn_invalid_escape_sequence (c , n , * first_invalid_escape ) < 0 ) {
4201+ /* We have not decref u before because first_invalid_escape points
4202+ inside u. */
4203+ Py_XDECREF (u );
4204+ Py_DECREF (v );
4205+ return NULL ;
4206+ }
4207+ }
41714208 Py_XDECREF (u );
41724209 return v ;
41734210}
41744211
4212+ static PyObject *
4213+ decode_bytes_with_escapes (struct compiling * c , const node * n , const char * s ,
4214+ size_t len )
4215+ {
4216+ const char * first_invalid_escape ;
4217+ PyObject * result = _PyBytes_DecodeEscape (s , len , NULL , 0 , NULL ,
4218+ & first_invalid_escape );
4219+ if (result == NULL )
4220+ return NULL ;
4221+
4222+ if (first_invalid_escape != NULL ) {
4223+ if (warn_invalid_escape_sequence (c , n , * first_invalid_escape ) < 0 ) {
4224+ Py_DECREF (result );
4225+ return NULL ;
4226+ }
4227+ }
4228+ return result ;
4229+ }
4230+
41754231/* Compile this expression in to an expr_ty. Add parens around the
41764232 expression, in order to allow leading spaces in the expression. */
41774233static expr_ty
@@ -4310,7 +4366,7 @@ fstring_find_literal(const char **str, const char *end, int raw,
43104366 literal_end - literal_start ,
43114367 NULL , NULL );
43124368 else
4313- * literal = decode_unicode_with_escapes (c , literal_start ,
4369+ * literal = decode_unicode_with_escapes (c , n , literal_start ,
43144370 literal_end - literal_start );
43154371 if (!* literal )
43164372 return -1 ;
@@ -5048,12 +5104,12 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
50485104 if (* rawmode )
50495105 * result = PyBytes_FromStringAndSize (s , len );
50505106 else
5051- * result = PyBytes_DecodeEscape ( s , len , NULL , /* ignored */ 0 , NULL );
5107+ * result = decode_bytes_with_escapes ( c , n , s , len );
50525108 } else {
50535109 if (* rawmode )
50545110 * result = PyUnicode_DecodeUTF8Stateful (s , len , NULL , NULL );
50555111 else
5056- * result = decode_unicode_with_escapes (c , s , len );
5112+ * result = decode_unicode_with_escapes (c , n , s , len );
50575113 }
50585114 return * result == NULL ? -1 : 0 ;
50595115}
0 commit comments