| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent cc28ed2 commit df69e75
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -167,16 +167,6 @@ def hash_constructors(self): | |||
| 167 | 167 | constructors = self.constructors_to_test.values() | |
| 168 | 168 | return itertools.chain.from_iterable(constructors) | |
| 169 | 169 | ||
| 170 | - @support.refcount_test | ||
| 171 | - @unittest.skipIf(c_hashlib is None, 'Require _hashlib module') | ||
| 172 | - def test_refleaks_in_hash___init__(self): | ||
| 173 | - gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') | ||
| 174 | - sha1_hash = c_hashlib.new('sha1') | ||
| 175 | - refs_before = gettotalrefcount() | ||
| 176 | - for i in range(100): | ||
| 177 | - sha1_hash.__init__('sha1') | ||
| 178 | - self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) | ||
| 179 | - | ||
| 180 | 170 | def test_hash_array(self): | |
| 181 | 171 | a = array.array("b", range(10)) | |
| 182 | 172 | for cons in self.hash_constructors: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + The _hashlib OpenSSL wrapper extension module is now PEP-384 compliant. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -46,21 +46,29 @@ | |||
| 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 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments