[3.13] gh-128632: fix segfault on nested __classdict__ type param (GH-128744) (#132085)

(cherry picked from commit 891c61c1fa)

Co-authored-by: Tomasz Pytel <tompytel@gmail.com>
This commit is contained in:
Tomasz Pytel 2025-04-04 11:23:40 -04:00 committed by GitHub
parent d8986b7f5e
commit 900dc2b034
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 53 additions and 13 deletions

View file

@ -2292,12 +2292,27 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
static int
symtable_visit_type_param_bound_or_default(
struct symtable *st, expr_ty e, identifier name,
void *key, const char *ste_scope_info)
type_param_ty tp, const char *ste_scope_info)
{
if (_PyUnicode_Equal(name, &_Py_ID(__classdict__))) {
PyObject *error_msg = PyUnicode_FromFormat("reserved name '%U' cannot be "
"used for type parameter", name);
PyErr_SetObject(PyExc_SyntaxError, error_msg);
Py_DECREF(error_msg);
PyErr_RangedSyntaxLocationObject(st->st_filename,
tp->lineno,
tp->col_offset + 1,
tp->end_lineno,
tp->end_col_offset + 1);
return 0;
}
if (e) {
int is_in_class = st->st_cur->ste_can_see_class_scope;
if (!symtable_enter_block(st, name, TypeVariableBlock, key, LOCATION(e)))
if (!symtable_enter_block(st, name, TypeVariableBlock, (void *)tp, LOCATION(e))) {
return 0;
}
st->st_cur->ste_can_see_class_scope = is_in_class;
if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(e))) {
@ -2341,12 +2356,12 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
// The only requirement for the key is that it is unique and it matches the logic in
// compile.c where the scope is retrieved.
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.bound, tp->v.TypeVar.name,
(void *)tp, ste_scope_info)) {
tp, ste_scope_info)) {
VISIT_QUIT(st, 0);
}
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVar.default_value, tp->v.TypeVar.name,
(void *)((uintptr_t)tp + 1), "a TypeVar default")) {
(type_param_ty)((uintptr_t)tp + 1), "a TypeVar default")) {
VISIT_QUIT(st, 0);
}
break;
@ -2356,7 +2371,7 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
}
if (!symtable_visit_type_param_bound_or_default(st, tp->v.TypeVarTuple.default_value, tp->v.TypeVarTuple.name,
(void *)tp, "a TypeVarTuple default")) {
tp, "a TypeVarTuple default")) {
VISIT_QUIT(st, 0);
}
break;
@ -2366,7 +2381,7 @@ symtable_visit_type_param(struct symtable *st, type_param_ty tp)
}
if (!symtable_visit_type_param_bound_or_default(st, tp->v.ParamSpec.default_value, tp->v.ParamSpec.name,
(void *)tp, "a ParamSpec default")) {
tp, "a ParamSpec default")) {
VISIT_QUIT(st, 0);
}
break;