46
46
#define PY_OPENSSL_HAS_BLAKE2 1
47
47
#endif
48
48
49
+ static PyModuleDef _hashlibmodule ;
50
+
51
+ typedef struct {
52
+ PyTypeObject * EVPtype ;
53
+ } _hashlibstate ;
54
+
55
+ #define _hashlibstate (o ) ((_hashlibstate *)PyModule_GetState(o))
56
+ #define _hashlibstate_global ((_hashlibstate *)PyModule_GetState(PyState_FindModule(&_hashlibmodule)))
57
+
58
+
49
59
typedef struct {
50
60
PyObject_HEAD
51
61
EVP_MD_CTX * ctx ; /* OpenSSL message digest context */
52
62
PyThread_type_lock lock ; /* OpenSSL context lock */
53
63
} EVPobject ;
54
64
55
65
56
- static PyTypeObject EVPtype ;
57
-
58
66
#include "clinic/_hashopenssl.c.h"
59
67
/*[clinic input]
60
68
module _hashlib
61
- class _hashlib.HASH "EVPobject *" "& EVPtype"
69
+ class _hashlib.HASH "EVPobject *" "((_hashlibstate *)PyModule_GetState(module))-> EVPtype"
62
70
[clinic start generated code]*/
63
- /*[clinic end generated code: output=da39a3ee5e6b4b0d input=a881a5092eecad28 ]*/
71
+ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=1adf85e8eb2ab979 ]*/
64
72
65
73
66
74
/* LCOV_EXCL_START */
@@ -231,7 +239,9 @@ py_digest_by_name(const char *name)
231
239
static EVPobject *
232
240
newEVPobject (void )
233
241
{
234
- EVPobject * retval = (EVPobject * )PyObject_New (EVPobject , & EVPtype );
242
+ EVPobject * retval = (EVPobject * )PyObject_New (
243
+ EVPobject , _hashlibstate_global -> EVPtype
244
+ );
235
245
if (retval == NULL ) {
236
246
return NULL ;
237
247
}
@@ -273,10 +283,12 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
273
283
static void
274
284
EVP_dealloc (EVPobject * self )
275
285
{
286
+ PyTypeObject * tp = Py_TYPE (self );
276
287
if (self -> lock != NULL )
277
288
PyThread_free_lock (self -> lock );
278
289
EVP_MD_CTX_free (self -> ctx );
279
290
PyObject_Del (self );
291
+ Py_DECREF (tp );
280
292
}
281
293
282
294
static int
@@ -501,46 +513,23 @@ PyDoc_STRVAR(hashtype_doc,
501
513
"name -- the hash algorithm being used by this object\n"
502
514
"digest_size -- number of bytes in this hashes output" );
503
515
504
- static PyTypeObject EVPtype = {
505
- PyVarObject_HEAD_INIT (NULL , 0 )
516
+ static PyType_Slot EVPtype_slots [] = {
517
+ {Py_tp_dealloc , EVP_dealloc },
518
+ {Py_tp_repr , EVP_repr },
519
+ {Py_tp_doc , (char * )hashtype_doc },
520
+ {Py_tp_methods , EVP_methods },
521
+ {Py_tp_getset , EVP_getseters },
522
+ {0 , 0 },
523
+ };
524
+
525
+ static PyType_Spec EVPtype_spec = {
506
526
"_hashlib.HASH" , /*tp_name*/
507
527
sizeof (EVPobject ), /*tp_basicsize*/
508
528
0 , /*tp_itemsize*/
509
- /* methods */
510
- (destructor )EVP_dealloc , /*tp_dealloc*/
511
- 0 , /*tp_vectorcall_offset*/
512
- 0 , /*tp_getattr*/
513
- 0 , /*tp_setattr*/
514
- 0 , /*tp_as_async*/
515
- (reprfunc )EVP_repr , /*tp_repr*/
516
- 0 , /*tp_as_number*/
517
- 0 , /*tp_as_sequence*/
518
- 0 , /*tp_as_mapping*/
519
- 0 , /*tp_hash*/
520
- 0 , /*tp_call*/
521
- 0 , /*tp_str*/
522
- 0 , /*tp_getattro*/
523
- 0 , /*tp_setattro*/
524
- 0 , /*tp_as_buffer*/
525
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /*tp_flags*/
526
- hashtype_doc , /*tp_doc*/
527
- 0 , /*tp_traverse*/
528
- 0 , /*tp_clear*/
529
- 0 , /*tp_richcompare*/
530
- 0 , /*tp_weaklistoffset*/
531
- 0 , /*tp_iter*/
532
- 0 , /*tp_iternext*/
533
- EVP_methods , /* tp_methods */
534
- NULL , /* tp_members */
535
- EVP_getseters , /* tp_getset */
536
- 0 , /* tp_base */
537
- 0 , /* tp_dict */
538
- 0 , /* tp_descr_get */
539
- 0 , /* tp_descr_set */
540
- 0 , /* tp_dictoffset */
529
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
530
+ EVPtype_slots
541
531
};
542
532
543
- \
544
533
static PyObject *
545
534
EVPnew (const EVP_MD * digest ,
546
535
const unsigned char * cp , Py_ssize_t len , int usedforsecurity )
@@ -1120,17 +1109,39 @@ static struct PyMethodDef EVP_functions[] = {
1120
1109
1121
1110
/* Initialize this module. */
1122
1111
1112
+ static int
1113
+ hashlib_traverse (PyObject * m , visitproc visit , void * arg )
1114
+ {
1115
+ _hashlibstate * state = _hashlibstate (m );
1116
+ Py_VISIT (state -> EVPtype );
1117
+ return 0 ;
1118
+ }
1119
+
1120
+ static int
1121
+ hashlib_clear (PyObject * m )
1122
+ {
1123
+ _hashlibstate * state = _hashlibstate (m );
1124
+ Py_CLEAR (state -> EVPtype );
1125
+ return 0 ;
1126
+ }
1127
+
1128
+ static void
1129
+ hashlib_free (void * m )
1130
+ {
1131
+ hashlib_clear ((PyObject * )m );
1132
+ }
1133
+
1123
1134
1124
1135
static struct PyModuleDef _hashlibmodule = {
1125
1136
PyModuleDef_HEAD_INIT ,
1126
1137
"_hashlib" ,
1127
1138
NULL ,
1128
- -1 ,
1139
+ sizeof ( _hashlibstate ) ,
1129
1140
EVP_functions ,
1130
1141
NULL ,
1131
- NULL ,
1132
- NULL ,
1133
- NULL
1142
+ hashlib_traverse ,
1143
+ hashlib_clear ,
1144
+ hashlib_free
1134
1145
};
1135
1146
1136
1147
PyMODINIT_FUNC
@@ -1144,19 +1155,21 @@ PyInit__hashlib(void)
1144
1155
ERR_load_crypto_strings ();
1145
1156
#endif
1146
1157
1147
- /* TODO build EVP_functions openssl_* entries dynamically based
1148
- * on what hashes are supported rather than listing many
1149
- * but having some be unsupported. Only init appropriate
1150
- * constants. */
1151
-
1152
- Py_TYPE (& EVPtype ) = & PyType_Type ;
1153
- if (PyType_Ready (& EVPtype ) < 0 )
1154
- return NULL ;
1158
+ m = PyState_FindModule (& _hashlibmodule );
1159
+ if (m != NULL ) {
1160
+ Py_INCREF (m );
1161
+ return m ;
1162
+ }
1155
1163
1156
1164
m = PyModule_Create (& _hashlibmodule );
1157
1165
if (m == NULL )
1158
1166
return NULL ;
1159
1167
1168
+ PyTypeObject * EVPtype = (PyTypeObject * )PyType_FromSpec (& EVPtype_spec );
1169
+ if (EVPtype == NULL )
1170
+ return NULL ;
1171
+ _hashlibstate (m )-> EVPtype = EVPtype ;
1172
+
1160
1173
openssl_md_meth_names = generate_hash_name_list ();
1161
1174
if (openssl_md_meth_names == NULL ) {
1162
1175
Py_DECREF (m );
@@ -1167,8 +1180,9 @@ PyInit__hashlib(void)
1167
1180
return NULL ;
1168
1181
}
1169
1182
1170
- Py_INCREF ((PyObject * )& EVPtype );
1171
- PyModule_AddObject (m , "HASH" , (PyObject * )& EVPtype );
1183
+ Py_INCREF ((PyObject * )_hashlibstate ( m ) -> EVPtype );
1184
+ PyModule_AddObject (m , "HASH" , (PyObject * )_hashlibstate ( m ) -> EVPtype );
1172
1185
1186
+ PyState_AddModule (m , & _hashlibmodule );
1173
1187
return m ;
1174
1188
}
0 commit comments