Skip to content

Commit 52a2df1

Browse files
authored
bpo-1635741: Convert _sha256 types to heap types (GH-22134)
Convert the _sha256 extension module types to heap types.
1 parent 15dcdb2 commit 52a2df1

File tree

3 files changed

+127
-103
lines changed

3 files changed

+127
-103
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Convert the :mod:`_sha256` extension module types to heap types.

Modules/clinic/sha256module.c.h

Lines changed: 16 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/sha256module.c

Lines changed: 110 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ typedef struct {
5151

5252
#include "clinic/sha256module.c.h"
5353

54+
typedef struct {
55+
PyTypeObject* sha224_type;
56+
PyTypeObject* sha256_type;
57+
} _sha256_state;
58+
59+
static inline _sha256_state*
60+
_sha256_get_state(PyObject *module)
61+
{
62+
void *state = PyModule_GetState(module);
63+
assert(state != NULL);
64+
return (_sha256_state *)state;
65+
}
66+
5467
/* When run on a little-endian CPU we need to perform byte reversal on an
5568
array of longwords. */
5669

@@ -365,28 +378,27 @@ sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
365378
* ------------------------------------------------------------------------
366379
*/
367380

368-
static PyTypeObject SHA224type;
369-
static PyTypeObject SHA256type;
370-
371381

372382
static SHAobject *
373-
newSHA224object(void)
383+
newSHA224object(_sha256_state *state)
374384
{
375-
return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
385+
return (SHAobject *)PyObject_New(SHAobject, state->sha224_type);
376386
}
377387

378388
static SHAobject *
379-
newSHA256object(void)
389+
newSHA256object(_sha256_state *state)
380390
{
381-
return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
391+
return (SHAobject *)PyObject_New(SHAobject, state->sha256_type);
382392
}
383393

384394
/* Internal methods for a hash object */
385395

386396
static void
387397
SHA_dealloc(PyObject *ptr)
388398
{
399+
PyTypeObject *tp = Py_TYPE(ptr);
389400
PyObject_Del(ptr);
401+
Py_DECREF(tp);
390402
}
391403

392404

@@ -395,21 +407,25 @@ SHA_dealloc(PyObject *ptr)
395407
/*[clinic input]
396408
SHA256Type.copy
397409
410+
cls:defining_class
411+
398412
Return a copy of the hash object.
399413
[clinic start generated code]*/
400414

401415
static PyObject *
402-
SHA256Type_copy_impl(SHAobject *self)
403-
/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/
416+
SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls)
417+
/*[clinic end generated code: output=9273f92c382be12f input=3137146fcb88e212]*/
404418
{
405419
SHAobject *newobj;
406-
407-
if (Py_IS_TYPE(self, &SHA256type)) {
408-
if ( (newobj = newSHA256object())==NULL)
420+
_sha256_state *state = PyType_GetModuleState(cls);
421+
if (Py_IS_TYPE(self, state->sha256_type)) {
422+
if ( (newobj = newSHA256object(state)) == NULL) {
409423
return NULL;
424+
}
410425
} else {
411-
if ( (newobj = newSHA224object())==NULL)
426+
if ( (newobj = newSHA224object(state))==NULL) {
412427
return NULL;
428+
}
413429
}
414430

415431
SHAcopy(self, newobj);
@@ -517,74 +533,27 @@ static PyMemberDef SHA_members[] = {
517533
{NULL} /* Sentinel */
518534
};
519535

520-
static PyTypeObject SHA224type = {
521-
PyVarObject_HEAD_INIT(NULL, 0)
522-
"_sha256.sha224", /*tp_name*/
523-
sizeof(SHAobject), /*tp_basicsize*/
524-
0, /*tp_itemsize*/
525-
/* methods */
526-
SHA_dealloc, /*tp_dealloc*/
527-
0, /*tp_vectorcall_offset*/
528-
0, /*tp_getattr*/
529-
0, /*tp_setattr*/
530-
0, /*tp_as_async*/
531-
0, /*tp_repr*/
532-
0, /*tp_as_number*/
533-
0, /*tp_as_sequence*/
534-
0, /*tp_as_mapping*/
535-
0, /*tp_hash*/
536-
0, /*tp_call*/
537-
0, /*tp_str*/
538-
0, /*tp_getattro*/
539-
0, /*tp_setattro*/
540-
0, /*tp_as_buffer*/
541-
Py_TPFLAGS_DEFAULT, /*tp_flags*/
542-
0, /*tp_doc*/
543-
0, /*tp_traverse*/
544-
0, /*tp_clear*/
545-
0, /*tp_richcompare*/
546-
0, /*tp_weaklistoffset*/
547-
0, /*tp_iter*/
548-
0, /*tp_iternext*/
549-
SHA_methods, /* tp_methods */
550-
SHA_members, /* tp_members */
551-
SHA_getseters, /* tp_getset */
536+
static PyType_Slot sha256_types_slots[] = {
537+
{Py_tp_dealloc, SHA_dealloc},
538+
{Py_tp_methods, SHA_methods},
539+
{Py_tp_members, SHA_members},
540+
{Py_tp_getset, SHA_getseters},
541+
{0,0}
552542
};
553543

554-
static PyTypeObject SHA256type = {
555-
PyVarObject_HEAD_INIT(NULL, 0)
556-
"_sha256.sha256", /*tp_name*/
557-
sizeof(SHAobject), /*tp_basicsize*/
558-
0, /*tp_itemsize*/
559-
/* methods */
560-
SHA_dealloc, /*tp_dealloc*/
561-
0, /*tp_vectorcall_offset*/
562-
0, /*tp_getattr*/
563-
0, /*tp_setattr*/
564-
0, /*tp_as_async*/
565-
0, /*tp_repr*/
566-
0, /*tp_as_number*/
567-
0, /*tp_as_sequence*/
568-
0, /*tp_as_mapping*/
569-
0, /*tp_hash*/
570-
0, /*tp_call*/
571-
0, /*tp_str*/
572-
0, /*tp_getattro*/
573-
0, /*tp_setattro*/
574-
0, /*tp_as_buffer*/
575-
Py_TPFLAGS_DEFAULT, /*tp_flags*/
576-
0, /*tp_doc*/
577-
0, /*tp_traverse*/
578-
0, /*tp_clear*/
579-
0, /*tp_richcompare*/
580-
0, /*tp_weaklistoffset*/
581-
0, /*tp_iter*/
582-
0, /*tp_iternext*/
583-
SHA_methods, /* tp_methods */
584-
SHA_members, /* tp_members */
585-
SHA_getseters, /* tp_getset */
544+
static PyType_Spec sha224_type_spec = {
545+
.name = "_sha256.sha224",
546+
.basicsize = sizeof(SHAobject),
547+
.flags = Py_TPFLAGS_DEFAULT,
548+
.slots = sha256_types_slots
586549
};
587550

551+
static PyType_Spec sha256_type_spec = {
552+
.name = "_sha256.sha256",
553+
.basicsize = sizeof(SHAobject),
554+
.flags = Py_TPFLAGS_DEFAULT,
555+
.slots = sha256_types_slots
556+
};
588557

589558
/* The single module-level function: new() */
590559

@@ -602,24 +571,29 @@ static PyObject *
602571
_sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity)
603572
/*[clinic end generated code: output=a1de327e8e1185cf input=9be86301aeb14ea5]*/
604573
{
605-
SHAobject *new;
606574
Py_buffer buf;
607575

608-
if (string)
576+
if (string) {
609577
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
578+
}
610579

611-
if ((new = newSHA256object()) == NULL) {
612-
if (string)
580+
_sha256_state *state = PyModule_GetState(module);
581+
582+
SHAobject *new;
583+
if ((new = newSHA256object(state)) == NULL) {
584+
if (string) {
613585
PyBuffer_Release(&buf);
586+
}
614587
return NULL;
615588
}
616589

617590
sha_init(new);
618591

619592
if (PyErr_Occurred()) {
620593
Py_DECREF(new);
621-
if (string)
594+
if (string) {
622595
PyBuffer_Release(&buf);
596+
}
623597
return NULL;
624598
}
625599
if (string) {
@@ -644,24 +618,27 @@ static PyObject *
644618
_sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity)
645619
/*[clinic end generated code: output=08be6b36569bc69c input=9fcfb46e460860ac]*/
646620
{
647-
SHAobject *new;
648621
Py_buffer buf;
649-
650-
if (string)
622+
if (string) {
651623
GET_BUFFER_VIEW_OR_ERROUT(string, &buf);
624+
}
652625

653-
if ((new = newSHA224object()) == NULL) {
654-
if (string)
626+
_sha256_state *state = PyModule_GetState(module);
627+
SHAobject *new;
628+
if ((new = newSHA224object(state)) == NULL) {
629+
if (string) {
655630
PyBuffer_Release(&buf);
631+
}
656632
return NULL;
657633
}
658634

659635
sha224_init(new);
660636

661637
if (PyErr_Occurred()) {
662638
Py_DECREF(new);
663-
if (string)
639+
if (string) {
664640
PyBuffer_Release(&buf);
641+
}
665642
return NULL;
666643
}
667644
if (string) {
@@ -681,25 +658,56 @@ static struct PyMethodDef SHA_functions[] = {
681658
{NULL, NULL} /* Sentinel */
682659
};
683660

661+
static int
662+
_sha256_traverse(PyObject *module, visitproc visit, void *arg)
663+
{
664+
_sha256_state *state = _sha256_get_state(module);
665+
Py_VISIT(state->sha224_type);
666+
Py_VISIT(state->sha256_type);
667+
return 0;
668+
}
669+
670+
static int
671+
_sha256_clear(PyObject *module)
672+
{
673+
_sha256_state *state = _sha256_get_state(module);
674+
Py_CLEAR(state->sha224_type);
675+
Py_CLEAR(state->sha256_type);
676+
return 0;
677+
}
678+
679+
static void
680+
_sha256_free(void *module)
681+
{
682+
_sha256_clear((PyObject *)module);
683+
}
684+
684685
static int sha256_exec(PyObject *module)
685686
{
686-
Py_SET_TYPE(&SHA224type, &PyType_Type);
687-
if (PyType_Ready(&SHA224type) < 0) {
687+
_sha256_state *state = _sha256_get_state(module);
688+
689+
state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec(
690+
module, &sha224_type_spec, NULL);
691+
692+
if (state->sha224_type == NULL) {
688693
return -1;
689694
}
690-
Py_SET_TYPE(&SHA256type, &PyType_Type);
691-
if (PyType_Ready(&SHA256type) < 0) {
695+
696+
state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec(
697+
module, &sha256_type_spec, NULL);
698+
699+
if (state->sha256_type == NULL) {
692700
return -1;
693701
}
694702

695-
Py_INCREF((PyObject *)&SHA224type);
696-
if (PyModule_AddObject(module, "SHA224Type", (PyObject *)&SHA224type) < 0) {
697-
Py_DECREF((PyObject *)&SHA224type);
703+
Py_INCREF((PyObject *)state->sha224_type);
704+
if (PyModule_AddObject(module, "SHA224Type", (PyObject *)state->sha224_type) < 0) {
705+
Py_DECREF((PyObject *)state->sha224_type);
698706
return -1;
699707
}
700-
Py_INCREF((PyObject *)&SHA256type);
701-
if (PyModule_AddObject(module, "SHA256Type", (PyObject *)&SHA256type) < 0) {
702-
Py_DECREF((PyObject *)&SHA256type);
708+
Py_INCREF((PyObject *)state->sha256_type);
709+
if (PyModule_AddObject(module, "SHA256Type", (PyObject *)state->sha256_type) < 0) {
710+
Py_DECREF((PyObject *)state->sha256_type);
703711
return -1;
704712
}
705713
return 0;
@@ -713,8 +721,12 @@ static PyModuleDef_Slot _sha256_slots[] = {
713721
static struct PyModuleDef _sha256module = {
714722
PyModuleDef_HEAD_INIT,
715723
.m_name = "_sha256",
724+
.m_size = sizeof(_sha256_state),
716725
.m_methods = SHA_functions,
717726
.m_slots = _sha256_slots,
727+
.m_traverse = _sha256_traverse,
728+
.m_clear = _sha256_clear,
729+
.m_free = _sha256_free
718730
};
719731

720732
/* Initialize this module. */

0 commit comments

Comments
 (0)