bpo-34441: Fix ABC.__subclasscheck__ crash on classes with invalid __subclasses__ (GH-8835)
The missing NULL check was reported by Svace static analyzer.
This commit is contained in:
parent
4c8555773a
commit
cdbf50cba1
|
@ -410,6 +410,36 @@ def test_factory(abc_ABCMeta, abc_get_cache_token):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
issubclass(C(), A)
|
issubclass(C(), A)
|
||||||
|
|
||||||
|
# bpo-34441: Check that issubclass() doesn't crash on bogus
|
||||||
|
# classes.
|
||||||
|
bogus_subclasses = [
|
||||||
|
None,
|
||||||
|
lambda x: [],
|
||||||
|
lambda: 42,
|
||||||
|
lambda: [42],
|
||||||
|
]
|
||||||
|
|
||||||
|
for i, func in enumerate(bogus_subclasses):
|
||||||
|
class S(metaclass=abc_ABCMeta):
|
||||||
|
__subclasses__ = func
|
||||||
|
|
||||||
|
with self.subTest(i=i):
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
issubclass(int, S)
|
||||||
|
|
||||||
|
# Also check that issubclass() propagates exceptions raised by
|
||||||
|
# __subclasses__.
|
||||||
|
exc_msg = "exception from __subclasses__"
|
||||||
|
|
||||||
|
def raise_exc():
|
||||||
|
raise Exception(exc_msg)
|
||||||
|
|
||||||
|
class S(metaclass=abc_ABCMeta):
|
||||||
|
__subclasses__ = raise_exc
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(Exception, exc_msg):
|
||||||
|
issubclass(int, S)
|
||||||
|
|
||||||
def test_all_new_methods_are_called(self):
|
def test_all_new_methods_are_called(self):
|
||||||
class A(metaclass=abc_ABCMeta):
|
class A(metaclass=abc_ABCMeta):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Fix crash when an ``ABC``-derived class with invalid ``__subclasses__`` is
|
||||||
|
passed as the second argument to :func:`issubclass()`. Patch by Alexey
|
||||||
|
Izbyshev.
|
|
@ -665,6 +665,9 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
|
||||||
|
|
||||||
/* 6. Check if it's a subclass of a subclass (recursive). */
|
/* 6. Check if it's a subclass of a subclass (recursive). */
|
||||||
subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
|
subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);
|
||||||
|
if (subclasses == NULL) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
if (!PyList_Check(subclasses)) {
|
if (!PyList_Check(subclasses)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
|
PyErr_SetString(PyExc_TypeError, "__subclasses__() must return a list");
|
||||||
goto end;
|
goto end;
|
||||||
|
|
Loading…
Reference in New Issue