Issue 28128: Print out better error/warning messages for invalid string escapes.

This commit is contained in:
Eric V. Smith 2016-10-31 09:22:08 -04:00
parent a99cdb21a7
commit 42454af094
8 changed files with 173 additions and 22 deletions

View file

@ -5877,9 +5877,10 @@ PyUnicode_AsUTF16String(PyObject *unicode)
static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
PyObject *
PyUnicode_DecodeUnicodeEscape(const char *s,
Py_ssize_t size,
const char *errors)
_PyUnicode_DecodeUnicodeEscape(const char *s,
Py_ssize_t size,
const char *errors,
const char **first_invalid_escape)
{
const char *starts = s;
_PyUnicodeWriter writer;
@ -5887,6 +5888,9 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
PyObject *errorHandler = NULL;
PyObject *exc = NULL;
// so we can remember if we've seen an invalid escape char or not
*first_invalid_escape = NULL;
if (size == 0) {
_Py_RETURN_UNICODE_EMPTY();
}
@ -6061,9 +6065,10 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
goto error;
default:
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"invalid escape sequence '\\%c'", c) < 0)
goto onError;
if (*first_invalid_escape == NULL) {
*first_invalid_escape = s-1; /* Back up one char, since we've
already incremented s. */
}
WRITE_ASCII_CHAR('\\');
WRITE_CHAR(c);
continue;
@ -6098,6 +6103,27 @@ PyUnicode_DecodeUnicodeEscape(const char *s,
return NULL;
}
PyObject *
PyUnicode_DecodeUnicodeEscape(const char *s,
Py_ssize_t size,
const char *errors)
{
const char *first_invalid_escape;
PyObject *result = _PyUnicode_DecodeUnicodeEscape(s, size, errors,
&first_invalid_escape);
if (result == NULL)
return NULL;
if (first_invalid_escape != NULL) {
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"invalid escape sequence '\\%c'",
*first_invalid_escape) < 0) {
Py_DECREF(result);
return NULL;
}
}
return result;
}
/* Return a Unicode-Escape string version of the Unicode object.
If quotes is true, the string is enclosed in u"" or u'' quotes as