Skip to content

Commit 6ede654

Browse files
Santhosh-Imiss-islington
authored andcommitted
gh-151912: Fix segfault in type() with NULL tp_new metaclasses (GH-151916)
(cherry picked from commit f160f16) Co-authored-by: Santhosh .I 🦇 <santhoshilaiyaraja2006@gmail.com>
1 parent 32ba4e1 commit 6ede654

3 files changed

Lines changed: 17 additions & 0 deletions

File tree

Lib/test/test_descr.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,15 @@ class X(C, int()):
814814
class X(int(), C):
815815
pass
816816

817+
@unittest.skipIf(_testcapi is None, 'need the _testcapi module')
818+
def test_type_with_null_new_metaclass(self):
819+
metaclass = _testcapi.HeapCTypeMetaclassNullNew
820+
base = _testcapi.pytype_fromspec_meta(metaclass)
821+
822+
# Exercise type_new's metaclass selection path, not a direct call.
823+
with self.assertRaisesRegex(TypeError, r"cannot create '.*' instances"):
824+
type("Derived", (base,), {})
825+
817826
def test_module_subclasses(self):
818827
# Testing Python subclass of module...
819828
log = []
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a crash in ``type()`` when selecting a metaclass whose ``tp_new`` slot is ``NULL``. Such metaclasses are now rejected with ``TypeError`` instead of causing a NULL pointer dereference.

Objects/typeobject.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4253,6 +4253,13 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type)
42534253

42544254
if (winner != ctx->metatype) {
42554255
if (winner->tp_new != type_new) {
4256+
/* Check if tp_new is NULL (cannot instantiate this type) */
4257+
if (winner->tp_new == NULL) {
4258+
PyErr_Format(PyExc_TypeError,
4259+
"cannot create '%.400s' instances",
4260+
winner->tp_name);
4261+
return -1;
4262+
}
42564263
/* Pass it to the winner */
42574264
*type = winner->tp_new(winner, ctx->args, ctx->kwds);
42584265
if (*type == NULL) {

0 commit comments

Comments
 (0)