mirror of
https://github.com/python/cpython
synced 2024-10-06 15:49:57 +00:00
gh-104482: Fix error handling bugs in ast.c (#104483)
This commit is contained in:
parent
26baa747c2
commit
8a3702f0c7
|
@ -2035,6 +2035,12 @@ def test_stdlib_validates(self):
|
|||
kwd_attrs=[],
|
||||
kwd_patterns=[ast.MatchStar()]
|
||||
),
|
||||
ast.MatchClass(
|
||||
constant_true, # invalid name
|
||||
patterns=[],
|
||||
kwd_attrs=['True'],
|
||||
kwd_patterns=[pattern_1]
|
||||
),
|
||||
ast.MatchSequence(
|
||||
[
|
||||
ast.MatchStar("True")
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fix three error handling bugs in ast.c's validation of pattern matching statements.
|
56
Python/ast.c
56
Python/ast.c
|
@ -46,6 +46,7 @@ static int validate_pattern(struct validator *, pattern_ty, int);
|
|||
static int
|
||||
validate_name(PyObject *name)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
assert(PyUnicode_Check(name));
|
||||
static const char * const forbidden[] = {
|
||||
"None",
|
||||
|
@ -65,12 +66,12 @@ validate_name(PyObject *name)
|
|||
static int
|
||||
validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
assert(!PyErr_Occurred());
|
||||
if (!asdl_seq_LEN(gens)) {
|
||||
PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < asdl_seq_LEN(gens); i++) {
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(gens); i++) {
|
||||
comprehension_ty comp = asdl_seq_GET(gens, i);
|
||||
if (!validate_expr(state, comp->target, Store) ||
|
||||
!validate_expr(state, comp->iter, Load) ||
|
||||
|
@ -83,8 +84,8 @@ validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
|
|||
static int
|
||||
validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
for (i = 0; i < asdl_seq_LEN(keywords); i++)
|
||||
assert(!PyErr_Occurred());
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++)
|
||||
if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
|
||||
return 0;
|
||||
return 1;
|
||||
|
@ -93,8 +94,8 @@ validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
|
|||
static int
|
||||
validate_args(struct validator *state, asdl_arg_seq *args)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
for (i = 0; i < asdl_seq_LEN(args); i++) {
|
||||
assert(!PyErr_Occurred());
|
||||
for (Py_ssize_t 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))
|
||||
|
@ -121,6 +122,7 @@ expr_context_name(expr_context_ty ctx)
|
|||
static int
|
||||
validate_arguments(struct validator *state, arguments_ty args)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -149,6 +151,7 @@ validate_arguments(struct validator *state, arguments_ty args)
|
|||
static int
|
||||
validate_constant(struct validator *state, PyObject *value)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
if (value == Py_None || value == Py_Ellipsis)
|
||||
return 1;
|
||||
|
||||
|
@ -205,6 +208,7 @@ validate_constant(struct validator *state, PyObject *value)
|
|||
static int
|
||||
validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
VALIDATE_POSITIONS(exp);
|
||||
int ret = -1;
|
||||
if (++state->recursion_depth > state->recursion_limit) {
|
||||
|
@ -465,6 +469,7 @@ ensure_literal_complex(expr_ty exp)
|
|||
static int
|
||||
validate_pattern_match_value(struct validator *state, expr_ty exp)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
if (!validate_expr(state, exp, Load)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -518,6 +523,7 @@ validate_pattern_match_value(struct validator *state, expr_ty exp)
|
|||
static int
|
||||
validate_capture(PyObject *name)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
if (_PyUnicode_EqualToASCIIString(name, "_")) {
|
||||
PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
|
||||
return 0;
|
||||
|
@ -528,6 +534,7 @@ validate_capture(PyObject *name)
|
|||
static int
|
||||
validate_pattern(struct validator *state, pattern_ty p, int star_ok)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
VALIDATE_POSITIONS(p);
|
||||
int ret = -1;
|
||||
if (++state->recursion_depth > state->recursion_limit) {
|
||||
|
@ -580,7 +587,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
|
||||
break;
|
||||
case MatchClass_kind:
|
||||
|
@ -611,6 +620,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
|
||||
PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
|
||||
|
@ -619,6 +631,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
|
||||
ret = 0;
|
||||
|
@ -685,6 +700,7 @@ _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
|
|||
static int
|
||||
validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
|
||||
validate_exprs(state, targets, ctx, 0);
|
||||
}
|
||||
|
@ -692,15 +708,16 @@ validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_contex
|
|||
static int
|
||||
validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
|
||||
}
|
||||
|
||||
static int
|
||||
validate_stmt(struct validator *state, stmt_ty stmt)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
VALIDATE_POSITIONS(stmt);
|
||||
int ret = -1;
|
||||
Py_ssize_t i;
|
||||
if (++state->recursion_depth > state->recursion_limit) {
|
||||
PyErr_SetString(PyExc_RecursionError,
|
||||
"maximum recursion depth exceeded during compilation");
|
||||
|
@ -771,7 +788,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
case With_kind:
|
||||
if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
|
||||
return 0;
|
||||
for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
|
||||
withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
|
||||
if (!validate_expr(state, item->context_expr, Load) ||
|
||||
(item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
|
||||
|
@ -782,7 +799,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
case AsyncWith_kind:
|
||||
if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
|
||||
return 0;
|
||||
for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
|
||||
withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
|
||||
if (!validate_expr(state, item->context_expr, Load) ||
|
||||
(item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
|
||||
|
@ -795,7 +812,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
|| !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
|
||||
match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
|
||||
if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
|
||||
|| (m->guard && !validate_expr(state, m->guard, Load))
|
||||
|
@ -830,7 +847,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
|
||||
for (Py_ssize_t 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 &&
|
||||
|
@ -856,7 +873,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
|
||||
excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
|
||||
if ((handler->v.ExceptHandler.type &&
|
||||
!validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
|
||||
|
@ -916,8 +933,8 @@ validate_stmt(struct validator *state, stmt_ty stmt)
|
|||
static int
|
||||
validate_stmts(struct validator *state, asdl_stmt_seq *seq)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
for (i = 0; i < asdl_seq_LEN(seq); i++) {
|
||||
assert(!PyErr_Occurred());
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) {
|
||||
stmt_ty stmt = asdl_seq_GET(seq, i);
|
||||
if (stmt) {
|
||||
if (!validate_stmt(state, stmt))
|
||||
|
@ -935,8 +952,8 @@ validate_stmts(struct validator *state, asdl_stmt_seq *seq)
|
|||
static int
|
||||
validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
for (i = 0; i < asdl_seq_LEN(exprs); i++) {
|
||||
assert(!PyErr_Occurred());
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) {
|
||||
expr_ty expr = asdl_seq_GET(exprs, i);
|
||||
if (expr) {
|
||||
if (!validate_expr(state, expr, ctx))
|
||||
|
@ -955,8 +972,8 @@ validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ct
|
|||
static int
|
||||
validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
for (i = 0; i < asdl_seq_LEN(patterns); i++) {
|
||||
assert(!PyErr_Occurred());
|
||||
for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) {
|
||||
pattern_ty pattern = asdl_seq_GET(patterns, i);
|
||||
if (!validate_pattern(state, pattern, star_ok)) {
|
||||
return 0;
|
||||
|
@ -972,6 +989,7 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_
|
|||
int
|
||||
_PyAST_Validate(mod_ty mod)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
int res = -1;
|
||||
struct validator state;
|
||||
PyThreadState *tstate;
|
||||
|
|
|
@ -567,6 +567,7 @@ PyCodeObject *
|
|||
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
|
||||
int optimize, PyArena *arena)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue