summaryrefslogtreecommitdiffstats
path: root/Modules/sha1module.c
diff options
context:
space:
mode:
authorMohamed Koubaa <koubaa.m@gmail.com>2020-09-06 10:09:51 (GMT)
committerGitHub <noreply@github.com>2020-09-06 10:09:51 (GMT)
commit63f102fe079ecb5cb7b921a1cf8bce4077a9d7e2 (patch)
tree55496c20a4e8da0303a51474ff3b559108683e9f /Modules/sha1module.c
parent5371a464ce88ffc88f3bb95cfd86f355b7d02953 (diff)
downloadcpython-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.c156
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);
}