From: Petr Vaganov Date: Tue, 30 Jun 2026 14:45:25 +0000 (+0700) Subject: gh-152682: Fix NULL dereference on OOM in `symtable_visit_type_param_bound_or_default... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10ed03edf128ed1101ab8d04bcd715f2033fec55;p=thirdparty%2FPython%2Fcpython.git gh-152682: Fix NULL dereference on OOM in `symtable_visit_type_param_bound_or_default` (#152684) In `symtable_visit_type_param_bound_or_default()`, when a reserved name (e.g. `__classdict__`) is used as a type parameter, `PyUnicode_FromFormat()` is called to build the SyntaxError message. If the allocation fails and returns NULL, the subsequent `PyErr_SetObject()` and `Py_DECREF()` calls would dereference NULL, causing a segfault. Fix by returning 0 immediately when `PyUnicode_FromFormat()` returns NULL. This propagates the MemoryError set by `PyUnicode_FromFormat()`. The bug was introduced in gh-128632 (commit 891c61c). --- diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 04e60c74ce1b..80577cf5c84f 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -2861,6 +2861,7 @@ import textwrap import unittest from test import support +from test.support.script_helper import assert_python_ok class SyntaxWarningTest(unittest.TestCase): def check_warning(self, code, errtext, filename="", mode="exec"): @@ -3201,6 +3202,22 @@ class A: class B[{name}]: pass """, "", mode="exec") + @support.nomemtest + def test_disallowed_type_param_names_oom(self): + # gh-152682: Don't crash on OOM when formatting the SyntaxError message + # in symtable_visit_type_param_bound_or_default. + code = textwrap.dedent("""\ + import _testcapi + _testcapi.set_nomemory(0) + try: + compile("class A[__classdict__]: pass", "", "exec") + except MemoryError: + pass + else: + raise RuntimeError('MemoryError not raised') + """) + assert_python_ok("-c", code) + @support.cpython_only def test_nested_named_except_blocks(self): code = "" diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-30-14-00-00.gh-issue-152682.yId7e5.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-30-14-00-00.gh-issue-152682.yId7e5.rst new file mode 100644 index 000000000000..aba0b594382b --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-30-14-00-00.gh-issue-152682.yId7e5.rst @@ -0,0 +1,3 @@ +Fix NULL pointer dereference in :func:`compile` when a reserved name (e.g. +``__classdict__``) is used as a type parameter name and memory allocation +fails while formatting the error message. diff --git a/Python/symtable.c b/Python/symtable.c index 00ac510fe76b..e3e89ab403a6 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -2678,6 +2678,9 @@ symtable_visit_type_param_bound_or_default( PyObject *error_msg = PyUnicode_FromFormat("reserved name '%U' cannot be " "used for type parameter", name); + if (error_msg == NULL) { + return 0; + } PyErr_SetObject(PyExc_SyntaxError, error_msg); Py_DECREF(error_msg); SET_ERROR_LOCATION(st->st_filename, LOCATION(tp));