mirror of
https://github.com/python/cpython.git
synced 2025-11-02 11:08:57 +00:00
Patch #50002: Display line information for bad \x escapes:
- recognize "SyntaxError"s by the print_file_and_line attribute. - add the syntaxerror attributes to all exceptions in compile.c. Fixes #221791
This commit is contained in:
parent
290d31e2fc
commit
cfeb3b6ab8
5 changed files with 55 additions and 17 deletions
|
|
@ -6,6 +6,9 @@ Type/class unification and new-style classes
|
||||||
|
|
||||||
Core and builtins
|
Core and builtins
|
||||||
|
|
||||||
|
- PyErr_Display will provide file and line information for all exceptions
|
||||||
|
that have an attribute print_file_and_line, not just SyntaxErrors.
|
||||||
|
|
||||||
- The UTF-8 codec will now encode and decode Unicode surrogates
|
- The UTF-8 codec will now encode and decode Unicode surrogates
|
||||||
correctly and without raising exceptions for unpaired ones.
|
correctly and without raising exceptions for unpaired ones.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -465,14 +465,21 @@ com_error(struct compiling *c, PyObject *exc, char *msg)
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
line = Py_None;
|
line = Py_None;
|
||||||
}
|
}
|
||||||
t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno,
|
if (exc == PyExc_SyntaxError) {
|
||||||
Py_None, line);
|
t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno,
|
||||||
if (t == NULL)
|
Py_None, line);
|
||||||
goto exit;
|
if (t == NULL)
|
||||||
w = Py_BuildValue("(OO)", v, t);
|
goto exit;
|
||||||
if (w == NULL)
|
w = Py_BuildValue("(OO)", v, t);
|
||||||
goto exit;
|
if (w == NULL)
|
||||||
PyErr_SetObject(exc, w);
|
goto exit;
|
||||||
|
PyErr_SetObject(exc, w);
|
||||||
|
} else {
|
||||||
|
/* Make sure additional exceptions are printed with
|
||||||
|
file and line, also. */
|
||||||
|
PyErr_SetObject(exc, v);
|
||||||
|
PyErr_SyntaxLocation(c->c_filename, c->c_lineno);
|
||||||
|
}
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(t);
|
Py_XDECREF(t);
|
||||||
Py_XDECREF(v);
|
Py_XDECREF(v);
|
||||||
|
|
@ -1153,7 +1160,8 @@ parsestr(struct compiling *com, char *s)
|
||||||
s++;
|
s++;
|
||||||
len = strlen(s);
|
len = strlen(s);
|
||||||
if (len > INT_MAX) {
|
if (len > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_OverflowError, "string to parse is too long");
|
com_error(com, PyExc_OverflowError,
|
||||||
|
"string to parse is too long");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (s[--len] != quote) {
|
if (s[--len] != quote) {
|
||||||
|
|
@ -1171,11 +1179,15 @@ parsestr(struct compiling *com, char *s)
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
if (unicode || Py_UnicodeFlag) {
|
if (unicode || Py_UnicodeFlag) {
|
||||||
if (rawmode)
|
if (rawmode)
|
||||||
return PyUnicode_DecodeRawUnicodeEscape(
|
v = PyUnicode_DecodeRawUnicodeEscape(
|
||||||
s, len, NULL);
|
s, len, NULL);
|
||||||
else
|
else
|
||||||
return PyUnicode_DecodeUnicodeEscape(
|
v = PyUnicode_DecodeUnicodeEscape(
|
||||||
s, len, NULL);
|
s, len, NULL);
|
||||||
|
if (v == NULL)
|
||||||
|
PyErr_SyntaxLocation(com->c_filename, com->c_lineno);
|
||||||
|
return v;
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (rawmode || strchr(s, '\\') == NULL)
|
if (rawmode || strchr(s, '\\') == NULL)
|
||||||
|
|
@ -1238,9 +1250,9 @@ parsestr(struct compiling *com, char *s)
|
||||||
*p++ = x;
|
*p++ = x;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"invalid \\x escape");
|
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
com_error(com, PyExc_ValueError,
|
||||||
|
"invalid \\x escape");
|
||||||
return NULL;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
*p++ = '\\';
|
*p++ = '\\';
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,9 @@ PyErr_WarnExplicit(PyObject *category, char *message,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* XXX There's a comment missing here */
|
/* Set file and line information for the current exception.
|
||||||
|
If the exception is not a SyntaxError, also sets additional attributes
|
||||||
|
to make printing of exceptions believe it is a syntax error. */
|
||||||
|
|
||||||
void
|
void
|
||||||
PyErr_SyntaxLocation(char *filename, int lineno)
|
PyErr_SyntaxLocation(char *filename, int lineno)
|
||||||
|
|
@ -596,6 +598,26 @@ PyErr_SyntaxLocation(char *filename, int lineno)
|
||||||
Py_DECREF(tmp);
|
Py_DECREF(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PyObject_SetAttrString(v, "offset", Py_None)) {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
if (exc != PyExc_SyntaxError) {
|
||||||
|
if (!PyObject_HasAttrString(v, "msg")) {
|
||||||
|
tmp = PyObject_Str(v);
|
||||||
|
if (tmp) {
|
||||||
|
if (PyObject_SetAttrString(v, "msg", tmp))
|
||||||
|
PyErr_Clear();
|
||||||
|
Py_DECREF(tmp);
|
||||||
|
} else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!PyObject_HasAttrString(v, "print_file_and_line")) {
|
||||||
|
if (PyObject_SetAttrString(v, "print_file_and_line",
|
||||||
|
Py_None))
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
PyErr_Restore(exc, v, tb);
|
PyErr_Restore(exc, v, tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -670,7 +670,8 @@ SyntaxError__classinit__(PyObject *klass)
|
||||||
PyObject_SetAttrString(klass, "filename", Py_None) ||
|
PyObject_SetAttrString(klass, "filename", Py_None) ||
|
||||||
PyObject_SetAttrString(klass, "lineno", Py_None) ||
|
PyObject_SetAttrString(klass, "lineno", Py_None) ||
|
||||||
PyObject_SetAttrString(klass, "offset", Py_None) ||
|
PyObject_SetAttrString(klass, "offset", Py_None) ||
|
||||||
PyObject_SetAttrString(klass, "text", Py_None))
|
PyObject_SetAttrString(klass, "text", Py_None) ||
|
||||||
|
PyObject_SetAttrString(klass, "print_file_and_line", Py_None))
|
||||||
{
|
{
|
||||||
retval = -1;
|
retval = -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -920,7 +920,7 @@ void PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
|
||||||
if (tb && tb != Py_None)
|
if (tb && tb != Py_None)
|
||||||
err = PyTraceBack_Print(tb, f);
|
err = PyTraceBack_Print(tb, f);
|
||||||
if (err == 0 &&
|
if (err == 0 &&
|
||||||
PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError))
|
PyObject_HasAttrString(v, "print_file_and_line"))
|
||||||
{
|
{
|
||||||
PyObject *message;
|
PyObject *message;
|
||||||
char *filename, *text;
|
char *filename, *text;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue