Skip to content

Commit edbc1fe

Browse files
[3.15] gh-151912: Fix segfault in type() with NULL tp_new metaclasses (GH-151916) (#153707)
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 9465c84 commit edbc1fe

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
@@ -5026,6 +5026,13 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type)
50265026

50275027
if (winner != ctx->metatype) {
50285028
if (winner->tp_new != type_new) {
5029+
/* Check if tp_new is NULL (cannot instantiate this type) */
5030+
if (winner->tp_new == NULL) {
5031+
PyErr_Format(PyExc_TypeError,
5032+
"cannot create '%.400s' instances",
5033+
winner->tp_name);
5034+
return -1;
5035+
}
50295036
/* Pass it to the winner */
50305037
*type = winner->tp_new(winner, ctx->args, ctx->kwds);
50315038
if (*type == NULL) {

0 commit comments

Comments
 (0)