https://github.com/python/cpython/commit/10ed03edf128ed1101ab8d04bcd715f2033fec55
commit: 10ed03edf128ed1101ab8d04bcd715f2033fec55
branch: main
author: Petr Vaganov <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-06-30T14:45:25Z
summary:
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).
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-06-30-14-00-00.gh-issue-152682.yId7e5.rst
M Lib/test/test_syntax.py
M Python/symtable.c
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 04e60c74ce1bea..80577cf5c84fac 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -2861,6 +2861,7 @@ def f(x: *b)
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="<testcase>", mode="exec"):
@@ -3201,6 +3202,22 @@ class A:
class B[{name}]: pass
""", "<testcase>", 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", "<string>", "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 00000000000000..aba0b594382bcf
--- /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 00ac510fe76b97..e3e89ab403a607 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));
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]