From 91554e4c5ca3c762998296522f854a7166ba84f0 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sun, 2 May 2021 09:47:45 +0200 Subject: [PATCH] bpo-43908: Mark ssl, hash, and hmac types as immutable (GH-25792) Signed-off-by: Christian Heimes --- Lib/test/test_hashlib.py | 9 +++++++++ Lib/test/test_hmac.py | 3 +++ Lib/test/test_ssl.py | 19 +++++++++++++++++++ Modules/_blake2/blake2b_impl.c | 2 +- Modules/_blake2/blake2s_impl.c | 2 +- Modules/_hashopenssl.c | 6 +++--- Modules/_sha3/sha3module.c | 2 +- Modules/_ssl.c | 10 +++++----- Modules/_ssl/cert.c | 2 +- Modules/md5module.c | 2 +- Modules/sha1module.c | 2 +- Modules/sha256module.c | 4 ++-- Modules/sha512module.c | 4 ++-- 13 files changed, 49 insertions(+), 18 deletions(-) diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index a515d3a3469..ad2ed69e24b 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -926,6 +926,15 @@ def test_hash_disallow_instanciation(self): ): HASHXOF() + def test_readonly_types(self): + for algorithm, constructors in self.constructors_to_test.items(): + # all other types have DISALLOW_INSTANTIATION + for constructor in constructors: + hash_type = type(constructor()) + with self.subTest(hash_type=hash_type): + with self.assertRaisesRegex(TypeError, "immutable type"): + hash_type.value = False + class KDFTests(unittest.TestCase): diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py index 22d74e9a113..964acd0361e 100644 --- a/Lib/test/test_hmac.py +++ b/Lib/test/test_hmac.py @@ -444,6 +444,9 @@ def test_internal_types(self): ): C_HMAC() + with self.assertRaisesRegex(TypeError, "immutable type"): + C_HMAC.value = None + @unittest.skipUnless(sha256_module is not None, 'need _sha256') def test_with_sha256_module(self): h = hmac.HMAC(b"key", b"hash this!", digestmod=sha256_module.sha256) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index f2b26c4b140..acb64f15fa0 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -345,6 +345,25 @@ def test_constants(self): ssl.OP_NO_TLSv1_2 self.assertEqual(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv23) + def test_ssl_types(self): + ssl_types = [ + _ssl._SSLContext, + _ssl._SSLSocket, + _ssl.MemoryBIO, + _ssl.Certificate, + _ssl.SSLSession, + _ssl.SSLError, + ] + for ssl_type in ssl_types: + with self.subTest(ssl_type=ssl_type): + with self.assertRaisesRegex(TypeError, "immutable type"): + ssl_type.value = None + with self.assertRaisesRegex( + TypeError, + "cannot create '_ssl.Certificate' instances" + ): + _ssl.Certificate() + def test_private_init(self): with self.assertRaisesRegex(TypeError, "public constructor"): with socket.socket() as s: diff --git a/Modules/_blake2/blake2b_impl.c b/Modules/_blake2/blake2b_impl.c index 5d108ed008a..8b0d60d02ac 100644 --- a/Modules/_blake2/blake2b_impl.c +++ b/Modules/_blake2/blake2b_impl.c @@ -409,6 +409,6 @@ static PyType_Slot blake2b_type_slots[] = { PyType_Spec blake2b_type_spec = { .name = "_blake2.blake2b", .basicsize = sizeof(BLAKE2bObject), - .flags = Py_TPFLAGS_DEFAULT, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, .slots = blake2b_type_slots }; diff --git a/Modules/_blake2/blake2s_impl.c b/Modules/_blake2/blake2s_impl.c index 85c2d4edad7..7ab3917aa1a 100644 --- a/Modules/_blake2/blake2s_impl.c +++ b/Modules/_blake2/blake2s_impl.c @@ -408,6 +408,6 @@ static PyType_Slot blake2s_type_slots[] = { PyType_Spec blake2s_type_spec = { .name = "_blake2.blake2s", .basicsize = sizeof(BLAKE2sObject), - .flags = Py_TPFLAGS_DEFAULT, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, .slots = blake2s_type_slots }; diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index de9bdd4f306..b2c67759e95 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -588,7 +588,7 @@ static PyType_Spec EVPtype_spec = { "_hashlib.HASH", /*tp_name*/ sizeof(EVPobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, EVPtype_slots }; @@ -737,7 +737,7 @@ static PyType_Spec EVPXOFtype_spec = { "_hashlib.HASHXOF", /*tp_name*/ sizeof(EVPobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, EVPXOFtype_slots }; @@ -1729,7 +1729,7 @@ static PyType_Slot HMACtype_slots[] = { PyType_Spec HMACtype_spec = { "_hashlib.HMAC", /* name */ sizeof(HMACobject), /* basicsize */ - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = HMACtype_slots, }; diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 27f69385cc3..aba7f6d4b45 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -525,7 +525,7 @@ static PyGetSetDef SHA3_getseters[] = { static PyType_Spec type_spec_obj = { \ .name = "_sha3." type_name, \ .basicsize = sizeof(SHA3object), \ - .flags = Py_TPFLAGS_DEFAULT, \ + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, \ .slots = type_slots \ } diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 91639277a83..5f03214ea3e 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -437,7 +437,7 @@ static PyType_Spec sslerror_type_spec = { "ssl.SSLError", sizeof(PyOSErrorObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE, sslerror_type_slots }; @@ -2906,7 +2906,7 @@ static PyType_Spec PySSLSocket_spec = { "_ssl._SSLSocket", sizeof(PySSLSocket), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, PySSLSocket_slots, }; @@ -4644,7 +4644,7 @@ static PyType_Spec PySSLContext_spec = { "_ssl._SSLContext", sizeof(PySSLContext), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, PySSLContext_slots, }; @@ -4850,7 +4850,7 @@ static PyType_Spec PySSLMemoryBIO_spec = { "_ssl.MemoryBIO", sizeof(PySSLMemoryBIO), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, PySSLMemoryBIO_slots, }; @@ -5025,7 +5025,7 @@ static PyType_Spec PySSLSession_spec = { "_ssl.SSLSession", sizeof(PySSLSession), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, PySSLSession_slots, }; diff --git a/Modules/_ssl/cert.c b/Modules/_ssl/cert.c index d2c26800881..bda66dc4d94 100644 --- a/Modules/_ssl/cert.c +++ b/Modules/_ssl/cert.c @@ -240,6 +240,6 @@ static PyType_Spec PySSLCertificate_spec = { "_ssl.Certificate", sizeof(PySSLCertificate), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, PySSLCertificate_slots, }; diff --git a/Modules/md5module.c b/Modules/md5module.c index 2ae94a456fd..9067c27a118 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -484,7 +484,7 @@ static PyType_Slot md5_type_slots[] = { static PyType_Spec md5_type_spec = { .name = "_md5.md5", .basicsize = sizeof(MD5object), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = md5_type_slots }; diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 9ac46c58a7f..1d4bde2d3b6 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -462,7 +462,7 @@ static PyType_Slot sha1_type_slots[] = { static PyType_Spec sha1_type_spec = { .name = "_sha1.sha1", .basicsize = sizeof(SHA1object), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = sha1_type_slots }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index ccb1862a99f..1edb9dc0500 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -544,14 +544,14 @@ static PyType_Slot sha256_types_slots[] = { static PyType_Spec sha224_type_spec = { .name = "_sha256.sha224", .basicsize = sizeof(SHAobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = sha256_types_slots }; static PyType_Spec sha256_type_spec = { .name = "_sha256.sha256", .basicsize = sizeof(SHAobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = sha256_types_slots }; diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 5e8572caf55..2bae0ce7877 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -602,7 +602,7 @@ static PyType_Slot sha512_sha384_type_slots[] = { static PyType_Spec sha512_sha384_type_spec = { .name = "_sha512.sha384", .basicsize = sizeof(SHAobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = sha512_sha384_type_slots }; @@ -619,7 +619,7 @@ static PyType_Slot sha512_sha512_type_slots[] = { static PyType_Spec sha512_sha512_type_spec = { .name = "_sha512.sha512", .basicsize = sizeof(SHAobject), - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, .slots = sha512_sha512_type_slots };