|
|
|
@ -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; |
|
|
|
} |
|
|
|
|