Skip to content

Commit 8808550

Browse files
petrvaganoffmiss-islington
authored andcommitted
gh-152682: Fix NULL dereference on OOM in symtable_visit_type_param_bound_or_default (GH-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). (cherry picked from commit 10ed03e) Co-authored-by: Petr Vaganov <petrvaganoff@gmail.com>
1 parent fd4965d commit 8808550

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

Lib/test/test_syntax.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,6 +2691,7 @@ def f(x: *b)
26912691
import unittest
26922692

26932693
from test import support
2694+
from test.support.script_helper import assert_python_ok
26942695

26952696
class SyntaxWarningTest(unittest.TestCase):
26962697
def check_warning(self, code, errtext, filename="<testcase>", mode="exec"):
@@ -3024,6 +3025,22 @@ class A:
30243025
class B[{name}]: pass
30253026
""", "<testcase>", mode="exec")
30263027

3028+
@support.nomemtest
3029+
def test_disallowed_type_param_names_oom(self):
3030+
# gh-152682: Don't crash on OOM when formatting the SyntaxError message
3031+
# in symtable_visit_type_param_bound_or_default.
3032+
code = textwrap.dedent("""\
3033+
import _testcapi
3034+
_testcapi.set_nomemory(0)
3035+
try:
3036+
compile("class A[__classdict__]: pass", "<string>", "exec")
3037+
except MemoryError:
3038+
pass
3039+
else:
3040+
raise RuntimeError('MemoryError not raised')
3041+
""")
3042+
assert_python_ok("-c", code)
3043+
30273044
@support.cpython_only
30283045
def test_nested_named_except_blocks(self):
30293046
code = ""
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix NULL pointer dereference in :func:`compile` when a reserved name (e.g.
2+
``__classdict__``) is used as a type parameter name and memory allocation
3+
fails while formatting the error message.

Python/symtable.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,9 @@ symtable_visit_type_param_bound_or_default(
26082608

26092609
PyObject *error_msg = PyUnicode_FromFormat("reserved name '%U' cannot be "
26102610
"used for type parameter", name);
2611+
if (error_msg == NULL) {
2612+
return 0;
2613+
}
26112614
PyErr_SetObject(PyExc_SyntaxError, error_msg);
26122615
Py_DECREF(error_msg);
26132616
SET_ERROR_LOCATION(st->st_filename, LOCATION(tp));

0 commit comments

Comments
 (0)