mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +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,6 +465,7 @@ com_error(struct compiling *c, PyObject *exc, char *msg)
 | 
				
			||||||
		Py_INCREF(Py_None);
 | 
							Py_INCREF(Py_None);
 | 
				
			||||||
		line = Py_None;
 | 
							line = Py_None;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if (exc == PyExc_SyntaxError) {
 | 
				
			||||||
		t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno,
 | 
							t = Py_BuildValue("(ziOO)", c->c_filename, c->c_lineno,
 | 
				
			||||||
				  Py_None, line);
 | 
									  Py_None, line);
 | 
				
			||||||
		if (t == NULL)
 | 
							if (t == NULL)
 | 
				
			||||||
| 
						 | 
					@ -473,6 +474,12 @@ com_error(struct compiling *c, PyObject *exc, char *msg)
 | 
				
			||||||
		if (w == NULL)
 | 
							if (w == NULL)
 | 
				
			||||||
			goto exit;
 | 
								goto exit;
 | 
				
			||||||
		PyErr_SetObject(exc, w);
 | 
							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