mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
Issue 28128: Print out better error/warning messages for invalid string escapes.
This commit is contained in:
parent
a99cdb21a7
commit
42454af094
8 changed files with 173 additions and 22 deletions
66
Python/ast.c
66
Python/ast.c
|
@ -4113,8 +4113,34 @@ decode_utf8(struct compiling *c, const char **sPtr, const char *end)
|
|||
return PyUnicode_DecodeUTF8(t, s - t, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
warn_invalid_escape_sequence(struct compiling *c, const node *n,
|
||||
char first_invalid_escape_char)
|
||||
{
|
||||
PyObject *msg = PyUnicode_FromFormat("invalid escape sequence \\%c",
|
||||
first_invalid_escape_char);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg,
|
||||
c->c_filename, LINENO(n),
|
||||
NULL, NULL) < 0 &&
|
||||
PyErr_ExceptionMatches(PyExc_DeprecationWarning))
|
||||
{
|
||||
const char *s = PyUnicode_AsUTF8(msg);
|
||||
if (s != NULL) {
|
||||
ast_error(c, n, s);
|
||||
}
|
||||
Py_DECREF(msg);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
decode_unicode_with_escapes(struct compiling *c, const char *s, size_t len)
|
||||
decode_unicode_with_escapes(struct compiling *c, const node *n, const char *s,
|
||||
size_t len)
|
||||
{
|
||||
PyObject *v, *u;
|
||||
char *buf;
|
||||
|
@ -4167,11 +4193,41 @@ decode_unicode_with_escapes(struct compiling *c, const char *s, size_t len)
|
|||
len = p - buf;
|
||||
s = buf;
|
||||
|
||||
v = PyUnicode_DecodeUnicodeEscape(s, len, NULL);
|
||||
const char *first_invalid_escape;
|
||||
v = _PyUnicode_DecodeUnicodeEscape(s, len, NULL, &first_invalid_escape);
|
||||
|
||||
if (v != NULL && first_invalid_escape != NULL) {
|
||||
if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) {
|
||||
/* We have not decref u before because first_invalid_escape points
|
||||
inside u. */
|
||||
Py_XDECREF(u);
|
||||
Py_DECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_XDECREF(u);
|
||||
return v;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
decode_bytes_with_escapes(struct compiling *c, const node *n, const char *s,
|
||||
size_t len)
|
||||
{
|
||||
const char *first_invalid_escape;
|
||||
PyObject *result = _PyBytes_DecodeEscape(s, len, NULL, 0, NULL,
|
||||
&first_invalid_escape);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
if (first_invalid_escape != NULL) {
|
||||
if (warn_invalid_escape_sequence(c, n, *first_invalid_escape) < 0) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Compile this expression in to an expr_ty. Add parens around the
|
||||
expression, in order to allow leading spaces in the expression. */
|
||||
static expr_ty
|
||||
|
@ -4310,7 +4366,7 @@ done:
|
|||
literal_end-literal_start,
|
||||
NULL, NULL);
|
||||
else
|
||||
*literal = decode_unicode_with_escapes(c, literal_start,
|
||||
*literal = decode_unicode_with_escapes(c, n, literal_start,
|
||||
literal_end-literal_start);
|
||||
if (!*literal)
|
||||
return -1;
|
||||
|
@ -5048,12 +5104,12 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
|
|||
if (*rawmode)
|
||||
*result = PyBytes_FromStringAndSize(s, len);
|
||||
else
|
||||
*result = PyBytes_DecodeEscape(s, len, NULL, /* ignored */ 0, NULL);
|
||||
*result = decode_bytes_with_escapes(c, n, s, len);
|
||||
} else {
|
||||
if (*rawmode)
|
||||
*result = PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL);
|
||||
else
|
||||
*result = decode_unicode_with_escapes(c, s, len);
|
||||
*result = decode_unicode_with_escapes(c, n, s, len);
|
||||
}
|
||||
return *result == NULL ? -1 : 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue