summaryrefslogtreecommitdiffstats
path: root/Modules/sha512module.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/sha512module.c')
-rw-r--r--Modules/sha512module.c235
1 files changed, 128 insertions, 107 deletions
diff --git a/Modules/sha512module.c b/Modules/sha512module.c
index aa2aeed..725098d 100644
--- a/Modules/sha512module.c
+++ b/Modules/sha512module.c
@@ -422,20 +422,29 @@ sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
* ------------------------------------------------------------------------
*/
-static PyTypeObject SHA384type;
-static PyTypeObject SHA512type;
+typedef struct {
+ PyTypeObject* sha384_type;
+ PyTypeObject* sha512_type;
+} SHA512State;
+static inline SHA512State*
+sha512_get_state(PyObject *module)
+{
+ void *state = PyModule_GetState(module);
+ assert(state != NULL);
+ return (SHA512State *)state;
+}
static SHAobject *
-newSHA384object(void)
+newSHA384object(SHA512State *st)
{
- return (SHAobject *)PyObject_New(SHAobject, &SHA384type);
+ return (SHAobject *)PyObject_New(SHAobject, st->sha384_type);
}
static SHAobject *
-newSHA512object(void)
+newSHA512object(SHA512State *st)
{
- return (SHAobject *)PyObject_New(SHAobject, &SHA512type);
+ return (SHAobject *)PyObject_New(SHAobject, st->sha512_type);
}
/* Internal methods for a hash object */
@@ -443,7 +452,9 @@ newSHA512object(void)
static void
SHA512_dealloc(PyObject *ptr)
{
+ PyTypeObject *tp = Py_TYPE(ptr);
PyObject_Del(ptr);
+ Py_DECREF(tp);
}
@@ -452,21 +463,27 @@ SHA512_dealloc(PyObject *ptr)
/*[clinic input]
SHA512Type.copy
+ cls: defining_class
+
Return a copy of the hash object.
[clinic start generated code]*/
static PyObject *
-SHA512Type_copy_impl(SHAobject *self)
-/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/
+SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=85ea5b47837a08e6 input=f673a18f66527c90]*/
{
SHAobject *newobj;
+ SHA512State *st = PyType_GetModuleState(cls);
- if (Py_IS_TYPE((PyObject*)self, &SHA512type)) {
- if ( (newobj = newSHA512object())==NULL)
+ if (Py_IS_TYPE((PyObject*)self, st->sha512_type)) {
+ if ( (newobj = newSHA512object(st))==NULL) {
return NULL;
- } else {
- if ( (newobj = newSHA384object())==NULL)
+ }
+ }
+ else {
+ if ( (newobj = newSHA384object(st))==NULL) {
return NULL;
+ }
}
SHAcopy(self, newobj);
@@ -574,74 +591,37 @@ static PyMemberDef SHA_members[] = {
{NULL} /* Sentinel */
};
-static PyTypeObject SHA384type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_sha512.sha384", /*tp_name*/
- sizeof(SHAobject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA512_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*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
+static PyType_Slot sha512_sha384_type_slots[] = {
+ {Py_tp_dealloc, SHA512_dealloc},
+ {Py_tp_methods, SHA_methods},
+ {Py_tp_members, SHA_members},
+ {Py_tp_getset, SHA_getseters},
+ {0,0}
+};
+
+static PyType_Spec sha512_sha384_type_spec = {
+ .name = "_sha512.sha384",
+ .basicsize = sizeof(SHAobject),
+ .flags = Py_TPFLAGS_DEFAULT,
+ .slots = sha512_sha384_type_slots
};
-static PyTypeObject SHA512type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_sha512.sha512", /*tp_name*/
- sizeof(SHAobject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA512_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*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
+static PyType_Slot sha512_sha512_type_slots[] = {
+ {Py_tp_dealloc, SHA512_dealloc},
+ {Py_tp_methods, SHA_methods},
+ {Py_tp_members, SHA_members},
+ {Py_tp_getset, SHA_getseters},
+ {0,0}
};
+// Using PyType_GetModuleState() on this type is safe since
+// it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag.
+static PyType_Spec sha512_sha512_type_spec = {
+ .name = "_sha512.sha512",
+ .basicsize = sizeof(SHAobject),
+ .flags = Py_TPFLAGS_DEFAULT,
+ .slots = sha512_sha512_type_slots
+};
/* The single module-level function: new() */
@@ -662,10 +642,12 @@ _sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity)
SHAobject *new;
Py_buffer buf;
+ SHA512State *st = sha512_get_state(module);
+
if (string)
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
- if ((new = newSHA512object()) == NULL) {
+ if ((new = newSHA512object(st)) == NULL) {
if (string)
PyBuffer_Release(&buf);
return NULL;
@@ -704,10 +686,12 @@ _sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity)
SHAobject *new;
Py_buffer buf;
+ SHA512State *st = sha512_get_state(module);
+
if (string)
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
- if ((new = newSHA384object()) == NULL) {
+ if ((new = newSHA384object(st)) == NULL) {
if (string)
PyBuffer_Release(&buf);
return NULL;
@@ -738,43 +722,80 @@ static struct PyMethodDef SHA_functions[] = {
{NULL, NULL} /* Sentinel */
};
+static int
+_sha512_traverse(PyObject *module, visitproc visit, void *arg)
+{
+ SHA512State *state = sha512_get_state(module);
+ Py_VISIT(state->sha384_type);
+ Py_VISIT(state->sha512_type);
+ return 0;
+}
-/* Initialize this module. */
+static int
+_sha512_clear(PyObject *module)
+{
+ SHA512State *state = sha512_get_state(module);
+ Py_CLEAR(state->sha384_type);
+ Py_CLEAR(state->sha512_type);
+ return 0;
+}
-static struct PyModuleDef _sha512module = {
- PyModuleDef_HEAD_INIT,
- "_sha512",
- NULL,
- -1,
- SHA_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
+static void
+_sha512_free(void *module)
+{
+ _sha512_clear((PyObject *)module);
+}
-PyMODINIT_FUNC
-PyInit__sha512(void)
+
+/* Initialize this module. */
+static int
+_sha512_exec(PyObject *m)
{
- PyObject *m;
+ SHA512State* st = sha512_get_state(m);
- Py_SET_TYPE(&SHA384type, &PyType_Type);
- if (PyType_Ready(&SHA384type) < 0) {
- return NULL;
+ st->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec(
+ m, &sha512_sha384_type_spec, NULL);
+
+ st->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec(
+ m, &sha512_sha512_type_spec, NULL);
+
+ if (st->sha384_type == NULL || st->sha512_type == NULL) {
+ return -1;
}
- Py_SET_TYPE(&SHA512type, &PyType_Type);
- if (PyType_Ready(&SHA512type) < 0) {
- return NULL;
+
+ Py_INCREF(st->sha384_type);
+ if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha384_type) < 0) {
+ Py_DECREF(st->sha384_type);
+ return -1;
}
- m = PyModule_Create(&_sha512module);
- if (m == NULL) {
- return NULL;
+ Py_INCREF(st->sha512_type);
+ if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha512_type) < 0) {
+ Py_DECREF(st->sha512_type);
+ return -1;
}
- Py_INCREF((PyObject *)&SHA384type);
- PyModule_AddObject(m, "SHA384Type", (PyObject *)&SHA384type);
- Py_INCREF((PyObject *)&SHA512type);
- PyModule_AddObject(m, "SHA512Type", (PyObject *)&SHA512type);
- return m;
+ return 0;
+}
+
+static PyModuleDef_Slot _sha512_slots[] = {
+ {Py_mod_exec, _sha512_exec},
+ {0, NULL}
+};
+
+static struct PyModuleDef _sha512module = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_sha512",
+ .m_size = sizeof(SHA512State),
+ .m_methods = SHA_functions,
+ .m_slots = _sha512_slots,
+ .m_traverse = _sha512_traverse,
+ .m_clear = _sha512_clear,
+ .m_free = _sha512_free
+};
+
+PyMODINIT_FUNC
+PyInit__sha512(void)
+{
+ return PyModuleDef_Init(&_sha512module);
}