diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2024-07-26 14:39:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-26 14:39:56 +0100 |
commit | bc94cf7e254e43318223553a7959115573c679a5 (patch) | |
tree | e35112d63c09f048b4c3a41259e79e5bfcfe983d /Python/symtable.c | |
parent | 2c42e13e80610a9dedcb15b57d142602e8143481 (diff) | |
download | cpython-bc94cf7e254e43318223553a7959115573c679a5.tar.gz cpython-bc94cf7e254e43318223553a7959115573c679a5.zip |
gh-122245: move checks for writes and shadowing of __debug__ to symtable (#122246)
Diffstat (limited to 'Python/symtable.c')
-rw-r--r-- | Python/symtable.c | 92 |
1 files changed, 85 insertions, 7 deletions
diff --git a/Python/symtable.c b/Python/symtable.c index c4508cac7f5..a5fa7588785 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1495,8 +1495,57 @@ error: } static int -symtable_add_def(struct symtable *st, PyObject *name, int flag, _Py_SourceLocation loc) +check_name(struct symtable *st, PyObject *name, _Py_SourceLocation loc, + expr_context_ty ctx) { + if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) { + PyErr_SetString(PyExc_SyntaxError, "cannot assign to __debug__"); + SET_ERROR_LOCATION(st->st_filename, loc); + return 0; + } + if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) { + PyErr_SetString(PyExc_SyntaxError, "cannot delete __debug__"); + SET_ERROR_LOCATION(st->st_filename, loc); + return 0; + } + return 1; +} + +static int +check_keywords(struct symtable *st, asdl_keyword_seq *keywords) +{ + for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++) { + keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i)); + if (key->arg && !check_name(st, key->arg, LOCATION(key), Store)) { + return 0; + } + } + return 1; +} + +static int +check_kwd_patterns(struct symtable *st, pattern_ty p) +{ + assert(p->kind == MatchClass_kind); + asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs; + asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns; + for (Py_ssize_t i = 0; i < asdl_seq_LEN(kwd_attrs); i++) { + _Py_SourceLocation loc = LOCATION(asdl_seq_GET(kwd_patterns, i)); + if (!check_name(st, asdl_seq_GET(kwd_attrs, i), loc, Store)) { + return 0; + } + } + return 1; +} + +static int +symtable_add_def_ctx(struct symtable *st, PyObject *name, int flag, + _Py_SourceLocation loc, expr_context_ty ctx) +{ + int write_mask = DEF_PARAM | DEF_LOCAL | DEF_IMPORT; + if ((flag & write_mask) && !check_name(st, name, loc, ctx)) { + return 0; + } if ((flag & DEF_TYPE_PARAM) && st->st_cur->ste_mangled_names != NULL) { if(PySet_Add(st->st_cur->ste_mangled_names, name) < 0) { return 0; @@ -1506,6 +1555,14 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag, _Py_SourceLocati } static int +symtable_add_def(struct symtable *st, PyObject *name, int flag, + _Py_SourceLocation loc) +{ + return symtable_add_def_ctx(st, name, flag, loc, + flag == USE ? Load : Store); +} + +static int symtable_enter_type_param_block(struct symtable *st, identifier name, void *ast, int has_defaults, int has_kwdefaults, enum _stmt_kind kind, _Py_SourceLocation loc) @@ -1757,6 +1814,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, type_param, s->v.ClassDef.type_params); } VISIT_SEQ(st, expr, s->v.ClassDef.bases); + if (!check_keywords(st, s->v.ClassDef.keywords)) { + VISIT_QUIT(st, 0); + } VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, LOCATION(s))) { @@ -1871,10 +1931,11 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT(st, expr, s->v.AnnAssign.value); } break; - case AugAssign_kind: + case AugAssign_kind: { VISIT(st, expr, s->v.AugAssign.target); VISIT(st, expr, s->v.AugAssign.value); break; + } case For_kind: VISIT(st, expr, s->v.For.target); VISIT(st, expr, s->v.For.iter); @@ -2311,6 +2372,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) case Call_kind: VISIT(st, expr, e->v.Call.func); VISIT_SEQ(st, expr, e->v.Call.args); + if (!check_keywords(st, e->v.Call.keywords)) { + VISIT_QUIT(st, 0); + } VISIT_SEQ_WITH_NULL(st, keyword, e->v.Call.keywords); break; case FormattedValue_kind: @@ -2326,6 +2390,9 @@ symtable_visit_expr(struct symtable *st, expr_ty e) break; /* The following exprs can be assignment targets. */ case Attribute_kind: + if (!check_name(st, e->v.Attribute.attr, LOCATION(e), e->v.Attribute.ctx)) { + VISIT_QUIT(st, 0); + } VISIT(st, expr, e->v.Attribute.value); break; case Subscript_kind: @@ -2344,9 +2411,11 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.Slice.step); break; case Name_kind: - if (!symtable_add_def(st, e->v.Name.id, - e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(e))) + if (!symtable_add_def_ctx(st, e->v.Name.id, + e->v.Name.ctx == Load ? USE : DEF_LOCAL, + LOCATION(e), e->v.Name.ctx)) { VISIT_QUIT(st, 0); + } /* Special-case super: it counts as a use of __class__ */ if (e->v.Name.ctx == Load && _PyST_IsFunctionLike(st->st_cur) && @@ -2472,19 +2541,26 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) break; case MatchStar_kind: if (p->v.MatchStar.name) { - symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p)); + if (!symtable_add_def(st, p->v.MatchStar.name, DEF_LOCAL, LOCATION(p))) { + VISIT_QUIT(st, 0); + } } break; case MatchMapping_kind: VISIT_SEQ(st, expr, p->v.MatchMapping.keys); VISIT_SEQ(st, pattern, p->v.MatchMapping.patterns); if (p->v.MatchMapping.rest) { - symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p)); + if (!symtable_add_def(st, p->v.MatchMapping.rest, DEF_LOCAL, LOCATION(p))) { + VISIT_QUIT(st, 0); + } } break; case MatchClass_kind: VISIT(st, expr, p->v.MatchClass.cls); VISIT_SEQ(st, pattern, p->v.MatchClass.patterns); + if (!check_kwd_patterns(st, p)) { + VISIT_QUIT(st, 0); + } VISIT_SEQ(st, pattern, p->v.MatchClass.kwd_patterns); break; case MatchAs_kind: @@ -2492,7 +2568,9 @@ symtable_visit_pattern(struct symtable *st, pattern_ty p) VISIT(st, pattern, p->v.MatchAs.pattern); } if (p->v.MatchAs.name) { - symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p)); + if (!symtable_add_def(st, p->v.MatchAs.name, DEF_LOCAL, LOCATION(p))) { + VISIT_QUIT(st, 0); + } } break; case MatchOr_kind: |