Skip to content

Commit 3be004f

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 e2818a7 commit 3be004f

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
@@ -815,6 +815,15 @@ class X(C, int()):
815815
class X(int(), C):
816816
pass
817817

818+
@unittest.skipIf(_testcapi is None, 'need the _testcapi module')
819+
def test_type_with_null_new_metaclass(self):
820+
metaclass = _testcapi.HeapCTypeMetaclassNullNew
821+
base = _testcapi.pytype_fromspec_meta(metaclass)
822+
823+
# Exercise type_new's metaclass selection path, not a direct call.
824+
with self.assertRaisesRegex(TypeError, r"cannot create '.*' instances"):
825+
type("Derived", (base,), {})
826+
818827
def test_module_subclasses(self):
819828
# Testing Python subclass of module...
820829
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
@@ -4733,6 +4733,13 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type)
47334733

47344734
if (winner != ctx->metatype) {
47354735
if (winner->tp_new != type_new) {
4736+
/* Check if tp_new is NULL (cannot instantiate this type) */
4737+
if (winner->tp_new == NULL) {
4738+
PyErr_Format(PyExc_TypeError,
4739+
"cannot create '%.400s' instances",
4740+
winner->tp_name);
4741+
return -1;
4742+
}
47364743
/* Pass it to the winner */
47374744
*type = winner->tp_new(winner, ctx->args, ctx->kwds);
47384745
if (*type == NULL) {

0 commit comments

Comments
 (0)