summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorPablo Galindo Salgado <Pablogsal@gmail.com>2022-05-30 18:30:15 (GMT)
committerGitHub <noreply@github.com>2022-05-30 18:30:15 (GMT)
commit5893b5db98b38b17750c0572c7209774a5034898 (patch)
tree0795c435c2939c765a39ed84dd7c21231c487cb8 /Python/ast.c
parent8136606769661c103c46d142e52ecbbbb88803f6 (diff)
downloadcpython-5893b5db98b38b17750c0572c7209774a5034898.zip
cpython-5893b5db98b38b17750c0572c7209774a5034898.tar.gz
cpython-5893b5db98b38b17750c0572c7209774a5034898.tar.bz2
gh-93351: Ensure the position information in AST nodes created by the parser is always consistent (GH-93352)
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 607281e..0885fe7 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -22,6 +22,27 @@ static int validate_stmt(struct validator *, stmt_ty);
static int validate_expr(struct validator *, expr_ty, expr_context_ty);
static int validate_pattern(struct validator *, pattern_ty, int);
+#define VALIDATE_POSITIONS(node) \
+ if (node->lineno > node->end_lineno) { \
+ PyErr_Format(PyExc_ValueError, \
+ "line %d-%d is not a valid range", \
+ node->lineno, node->end_lineno); \
+ return 0; \
+ } \
+ if ((node->lineno < 0 && node->end_lineno != node->lineno) || \
+ (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \
+ PyErr_Format(PyExc_ValueError, \
+ "line %d-%d, column %d-%d is not a valid range", \
+ node->lineno, node->end_lineno, node->col_offset, node->end_col_offset); \
+ return 0; \
+ } \
+ if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \
+ PyErr_Format(PyExc_ValueError, \
+ "line %d, column %d-%d is not a valid range", \
+ node->lineno, node->col_offset, node->end_col_offset); \
+ return 0; \
+ }
+
static int
validate_name(PyObject *name)
{
@@ -75,6 +96,7 @@ validate_args(struct validator *state, asdl_arg_seq *args)
Py_ssize_t i;
for (i = 0; i < asdl_seq_LEN(args); i++) {
arg_ty arg = asdl_seq_GET(args, i);
+ VALIDATE_POSITIONS(arg);
if (arg->annotation && !validate_expr(state, arg->annotation, Load))
return 0;
}
@@ -183,6 +205,7 @@ validate_constant(struct validator *state, PyObject *value)
static int
validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
{
+ VALIDATE_POSITIONS(exp);
int ret = -1;
if (++state->recursion_depth > state->recursion_limit) {
PyErr_SetString(PyExc_RecursionError,
@@ -505,6 +528,7 @@ validate_capture(PyObject *name)
static int
validate_pattern(struct validator *state, pattern_ty p, int star_ok)
{
+ VALIDATE_POSITIONS(p);
int ret = -1;
if (++state->recursion_depth > state->recursion_limit) {
PyErr_SetString(PyExc_RecursionError,
@@ -674,6 +698,7 @@ validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
static int
validate_stmt(struct validator *state, stmt_ty stmt)
{
+ VALIDATE_POSITIONS(stmt);
int ret = -1;
Py_ssize_t i;
if (++state->recursion_depth > state->recursion_limit) {
@@ -807,6 +832,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
}
for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
+ VALIDATE_POSITIONS(handler);
if ((handler->v.ExceptHandler.type &&
!validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
!validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))