Skip to content

Commit 7f79179

Browse files
gh-159294: Fix crash when creating an ExceptionGroup fails with MemoryError
BaseExceptionGroup_new() passed the result of BaseException_new() to PyBaseExceptionGroupObject_CAST() before checking it for NULL. The cast asserts the type of its argument, so a debug build dereferenced NULL instead of raising MemoryError.
1 parent 627eabf commit 7f79179

3 files changed

Lines changed: 16 additions & 3 deletions

File tree

‎Lib/test/test_exception_group.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import collections
22
import types
33
import unittest
4+
from test import support
45
from test.support import (skip_emscripten_stack_overflow,
56
skip_wasi_stack_overflow, run_with_limited_c_stack,
67
exceeds_recursion_limit)
@@ -130,6 +131,15 @@ class MyBEG(BaseExceptionGroup):
130131
type(MyBEG("eg", [ValueError(12), KeyboardInterrupt(42)])),
131132
MyBEG)
132133

134+
@support.nomemtest
135+
def test_no_memory(self):
136+
import _testcapi
137+
# A tuple of exceptions is not copied, so the first allocation
138+
# is the one of the exception group itself.
139+
excs = (ValueError(1),)
140+
with self.assertRaises(MemoryError):
141+
_testcapi.call_with_nomemory(0, 0, ExceptionGroup, "eg", excs)
142+
133143

134144
class StrAndReprTests(unittest.TestCase):
135145
def test_ExceptionGroup(self):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a crash in a debug build when creating an :exc:`ExceptionGroup` or
2+
:exc:`BaseExceptionGroup` fails with :exc:`MemoryError`. Patch by Christian
3+
Aurich Zanettini Martins.

‎Objects/exceptions.c‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -974,11 +974,11 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
974974
*/
975975
cls = (PyTypeObject*)PyExc_BaseExceptionGroup;
976976
}
977-
PyBaseExceptionGroupObject *self =
978-
PyBaseExceptionGroupObject_CAST(BaseException_new(cls, args, kwds));
979-
if (!self) {
977+
PyObject *op = BaseException_new(cls, args, kwds);
978+
if (!op) {
980979
goto error;
981980
}
981+
PyBaseExceptionGroupObject *self = PyBaseExceptionGroupObject_CAST(op);
982982

983983
self->msg = Py_NewRef(message);
984984
self->excs = exceptions;

0 commit comments

Comments
 (0)