Skip to content

Commit 71439d0

Browse files
author
Erlend E. Aasland
committed
bpo-43916: Apply Py_TPFLAGS_DISALLOW_INSTANTIATION to selected types
Also add tests
1 parent 0cad068 commit 71439d0

20 files changed

+85
-27
lines changed

Lib/test/test_array.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ def test_bad_constructor(self):
4040
self.assertRaises(TypeError, array.array, 'xx')
4141
self.assertRaises(ValueError, array.array, 'x')
4242

43+
@support.cpython_only
44+
def test_uninitialised_new(self):
45+
# Prevent heap types from being created uninitialised (bpo-43916)
46+
tp = type(iter(array.array('I')))
47+
self.assertRaises(TypeError, tp)
48+
4349
@support.cpython_only
4450
def test_immutable(self):
4551
# bpo-43908: check that array.array is immutable

Lib/test/test_curses.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import tempfile
77
import unittest
88

9-
from test.support import requires, verbose, SaveSignals
9+
from test.support import requires, verbose, SaveSignals, cpython_only
1010
from test.support.import_helper import import_module
1111

1212
# Optionally test curses module. This currently requires that the
@@ -1046,6 +1046,7 @@ def __del__(self):
10461046
panel.set_userptr(A())
10471047
panel.set_userptr(None)
10481048

1049+
@cpython_only
10491050
@requires_curses_func('panel')
10501051
def test_new_curses_panel(self):
10511052
w = curses.newwin(10, 10)

Lib/test/test_dbm_gnu.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from test import support
2-
from test.support import import_helper
2+
from test.support import import_helper, cpython_only
33
gdbm = import_helper.import_module("dbm.gnu") #skip if not supported
44
import unittest
55
import os
@@ -27,6 +27,13 @@ def tearDown(self):
2727
self.g.close()
2828
unlink(filename)
2929

30+
@cpython_only
31+
def test_uninitialised_new(self):
32+
# Prevent heap types from being created uninitialised (bpo-43916)
33+
self.g = gdbm.open(filename, 'c')
34+
tp = type(self.g)
35+
self.assertRaises(TypeError, tp)
36+
3037
def test_key_methods(self):
3138
self.g = gdbm.open(filename, 'c')
3239
self.assertEqual(self.g.keys(), [])

Lib/test/test_functools.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,12 @@ class TestCmpToKeyC(TestCmpToKey, unittest.TestCase):
948948
if c_functools:
949949
cmp_to_key = c_functools.cmp_to_key
950950

951+
@support.cpython_only
952+
def test_uninitialised_new(self):
953+
# Prevent heap types from being created uninitialised (bpo-43916)
954+
tp = type(c_functools.cmp_to_key(None))
955+
self.assertRaises(TypeError, tp)
956+
951957

952958
class TestCmpToKeyPy(TestCmpToKey, unittest.TestCase):
953959
cmp_to_key = staticmethod(py_functools.cmp_to_key)

Lib/test/test_re.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,15 @@ def test_signedness(self):
22152215
self.assertGreaterEqual(sre_compile.MAXREPEAT, 0)
22162216
self.assertGreaterEqual(sre_compile.MAXGROUPS, 0)
22172217

2218+
@cpython_only
2219+
def test_uninitialised_new(self):
2220+
# Prevent heap types from being created uninitialised (bpo-43916)
2221+
self.assertRaises(TypeError, re.Match)
2222+
self.assertRaises(TypeError, re.Pattern)
2223+
pat = re.compile("")
2224+
tp = type(pat.scanner(""))
2225+
self.assertRaises(TypeError, tp)
2226+
22182227

22192228
class ExternalTests(unittest.TestCase):
22202229

Lib/test/test_tcl.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,11 @@ def check(value):
736736
check('{\n')
737737
check('}\n')
738738

739+
@support.cpython_only
739740
def test_new_tcl_obj(self):
740741
self.assertRaises(TypeError, _tkinter.Tcl_Obj)
742+
self.assertRaises(TypeError, _tkinter.TkttType)
743+
self.assertRaises(TypeError, _tkinter.TkappType)
741744

742745
class BigmemTclTest(unittest.TestCase):
743746

Lib/test/test_threading.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ def func(): pass
119119
thread = threading.Thread(target=func)
120120
self.assertEqual(thread.name, "Thread-5 (func)")
121121

122+
@cpython_only
123+
def test_uninitialised_new(self):
124+
# Prevent heap types from being created uninitialised (bpo-43916)
125+
lock = threading.Lock()
126+
tp = type(lock)
127+
self.assertRaises(TypeError, tp)
128+
122129
# Create a bunch of threads, let each do some work, wait until all are
123130
# done.
124131
def test_various_ops(self):

Lib/test/test_unicodedata.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import sys
1212
import unicodedata
1313
import unittest
14-
from test.support import open_urlresource, requires_resource, script_helper
14+
from test.support import (open_urlresource, requires_resource, script_helper,
15+
cpython_only)
1516

1617

1718
class UnicodeMethodsTest(unittest.TestCase):
@@ -225,6 +226,11 @@ def test_east_asian_width_9_0_changes(self):
225226

226227
class UnicodeMiscTest(UnicodeDatabaseTest):
227228

229+
@cpython_only
230+
def test_uninitialised_new(self):
231+
# Prevent heap types from being created uninitialised (bpo-43916)
232+
self.assertRaises(TypeError, unicodedata.UCD)
233+
228234
def test_failed_import_during_compiling(self):
229235
# Issue 4367
230236
# Decoding \N escapes requires the unicodedata module. If it can't be

Lib/test/test_zlib.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ def test_overflow(self):
129129
with self.assertRaisesRegex(OverflowError, 'int too large'):
130130
zlib.decompressobj().flush(sys.maxsize + 1)
131131

132+
@support.cpython_only
133+
def test_uninitialised_new(self):
134+
# Prevent heap types from being created uninitialised (bpo-43916)
135+
comp_type = type(zlib.compressobj())
136+
decomp_type = type(zlib.decompressobj())
137+
self.assertRaises(TypeError, comp_type)
138+
self.assertRaises(TypeError, decomp_type)
139+
132140

133141
class BaseCompressTestCase(object):
134142
def check_big_compress_buffer(self, size, compress_func):

Modules/_dbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ static PyType_Spec dbmtype_spec = {
414414
// dbmtype_spec does not have Py_TPFLAGS_BASETYPE flag
415415
// which prevents to create a subclass.
416416
// So calling PyType_GetModuleState() in this file is always safe.
417-
.flags = Py_TPFLAGS_DEFAULT,
417+
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
418418
.slots = dbmtype_spec_slots,
419419
};
420420

0 commit comments

Comments
 (0)