diff options
author | Mohamed Koubaa <koubaa.m@gmail.com> | 2020-09-06 10:09:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-06 10:09:51 (GMT) |
commit | 63f102fe079ecb5cb7b921a1cf8bce4077a9d7e2 (patch) | |
tree | 55496c20a4e8da0303a51474ff3b559108683e9f /Modules/sha1module.c | |
parent | 5371a464ce88ffc88f3bb95cfd86f355b7d02953 (diff) | |
download | cpython-63f102fe079ecb5cb7b921a1cf8bce4077a9d7e2.zip cpython-63f102fe079ecb5cb7b921a1cf8bce4077a9d7e2.tar.gz cpython-63f102fe079ecb5cb7b921a1cf8bce4077a9d7e2.tar.bz2 |
bpo-1635741: Port _sha1, _sha512, _md5 to multiphase init (GH-21818)
Port the _sha1, _sha512, and _md5 extension modules
to multi-phase initialization API (PEP 489).
Diffstat (limited to 'Modules/sha1module.c')
-rw-r--r-- | Modules/sha1module.c | 156 |
1 files changed, 92 insertions, 64 deletions
diff --git a/Modules/sha1module.c b/Modules/sha1module.c index b0656d8..c22437d 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -295,13 +295,22 @@ sha1_done(struct sha1_state *sha1, unsigned char *out) * ------------------------------------------------------------------------ */ -static PyTypeObject SHA1type; +typedef struct { + PyTypeObject* sha1_type; +} SHA1State; +static inline SHA1State* +sha1_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (SHA1State *)state; +} static SHA1object * -newSHA1object(void) +newSHA1object(SHA1State *st) { - return (SHA1object *)PyObject_New(SHA1object, &SHA1type); + return (SHA1object *)PyObject_New(SHA1object, st->sha1_type); } @@ -310,7 +319,9 @@ newSHA1object(void) static void SHA1_dealloc(PyObject *ptr) { + PyTypeObject *tp = Py_TYPE(ptr); PyObject_Del(ptr); + Py_DECREF(tp); } @@ -319,16 +330,19 @@ SHA1_dealloc(PyObject *ptr) /*[clinic input] SHA1Type.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -SHA1Type_copy_impl(SHA1object *self) -/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ +SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls) +/*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/ { - SHA1object *newobj; + SHA1State *st = PyType_GetModuleState(cls); - if ((newobj = newSHA1object()) == NULL) + SHA1object *newobj; + if ((newobj = newSHA1object(st)) == NULL) return NULL; newobj->hash_state = self->hash_state; @@ -422,7 +436,6 @@ sha1_get_digest_size(PyObject *self, void *closure) return PyLong_FromLong(SHA1_DIGESTSIZE); } - static PyGetSetDef SHA1_getseters[] = { {"block_size", (getter)SHA1_get_block_size, NULL, @@ -439,40 +452,19 @@ static PyGetSetDef SHA1_getseters[] = { {NULL} /* Sentinel */ }; -static PyTypeObject SHA1type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha1.sha1", /*tp_name*/ - sizeof(SHA1object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - SHA1_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - SHA1_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA1_getseters, /* tp_getset */ +static PyType_Slot sha1_type_slots[] = { + {Py_tp_dealloc, SHA1_dealloc}, + {Py_tp_methods, SHA1_methods}, + {Py_tp_getset, SHA1_getseters}, + {0,0} }; +static PyType_Spec sha1_type_spec = { + .name = "_sha1.sha1", + .basicsize = sizeof(SHA1object), + .flags = Py_TPFLAGS_DEFAULT, + .slots = sha1_type_slots +}; /* The single module-level function: new() */ @@ -496,7 +488,8 @@ _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) if (string) GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - if ((new = newSHA1object()) == NULL) { + SHA1State *st = sha1_get_state(module); + if ((new = newSHA1object(st)) == NULL) { if (string) PyBuffer_Release(&buf); return NULL; @@ -526,37 +519,72 @@ static struct PyMethodDef SHA1_functions[] = { {NULL, NULL} /* Sentinel */ }; +static int +_sha1_traverse(PyObject *module, visitproc visit, void *arg) +{ + SHA1State *state = sha1_get_state(module); + Py_VISIT(state->sha1_type); + return 0; +} + +static int +_sha1_clear(PyObject *module) +{ + SHA1State *state = sha1_get_state(module); + Py_CLEAR(state->sha1_type); + return 0; +} + +static void +_sha1_free(void *module) +{ + _sha1_clear((PyObject *)module); +} + +static int +_sha1_exec(PyObject *module) +{ + SHA1State* st = sha1_get_state(module); + + st->sha1_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha1_type_spec, NULL); + + if (st->sha1_type == NULL) { + return -1; + } + + Py_INCREF(st->sha1_type); + if (PyModule_AddObject(module, + "SHA1Type", + (PyObject *)st->sha1_type) < 0) { + Py_DECREF(st->sha1_type); + return -1; + } + + return 0; +} + /* Initialize this module. */ +static PyModuleDef_Slot _sha1_slots[] = { + {Py_mod_exec, _sha1_exec}, + {0, NULL} +}; + static struct PyModuleDef _sha1module = { PyModuleDef_HEAD_INIT, - "_sha1", - NULL, - -1, - SHA1_functions, - NULL, - NULL, - NULL, - NULL + .m_name = "_sha1", + .m_size = sizeof(SHA1State), + .m_methods = SHA1_functions, + .m_slots = _sha1_slots, + .m_traverse = _sha1_traverse, + .m_clear = _sha1_clear, + .m_free = _sha1_free }; PyMODINIT_FUNC PyInit__sha1(void) { - PyObject *m; - - Py_SET_TYPE(&SHA1type, &PyType_Type); - if (PyType_Ready(&SHA1type) < 0) { - return NULL; - } - - m = PyModule_Create(&_sha1module); - if (m == NULL) { - return NULL; - } - - Py_INCREF((PyObject *)&SHA1type); - PyModule_AddObject(m, "SHA1Type", (PyObject *)&SHA1type); - return m; + return PyModuleDef_Init(&_sha1module); } |