Skip to content

Commit 10c77d7

Browse files
committed
[3.14] pythongh-116946: fully implement GC protocol for _hashlib objects (pythonGH-138289)
(cherry picked from commit 6f1dd95) Co-authored-by: Bénédikt Tran <[email protected]>
1 parent 5ec6d56 commit 10c77d7

File tree

1 file changed

+58
-19
lines changed

1 file changed

+58
-19
lines changed

Modules/_hashopenssl.c

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,9 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type
500500
static EVPobject *
501501
newEVPobject(PyTypeObject *type)
502502
{
503-
EVPobject *retval = PyObject_New(EVPobject, type);
503+
assert(type != NULL);
504+
assert(type->tp_alloc != NULL);
505+
EVPobject *retval = (EVPobject *)type->tp_alloc(type, 0);
504506
if (retval == NULL) {
505507
return NULL;
506508
}
@@ -541,13 +543,21 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len)
541543
static void
542544
EVP_dealloc(PyObject *op)
543545
{
546+
PyTypeObject *tp = Py_TYPE(op);
547+
PyObject_GC_UnTrack(op);
544548
EVPobject *self = EVPobject_CAST(op);
545-
PyTypeObject *tp = Py_TYPE(self);
546549
EVP_MD_CTX_free(self->ctx);
547-
PyObject_Free(self);
550+
tp->tp_free(self);
548551
Py_DECREF(tp);
549552
}
550553

554+
static int
555+
EVP_traverse(PyObject *op, visitproc visit, void *arg)
556+
{
557+
Py_VISIT(Py_TYPE(op));
558+
return 0;
559+
}
560+
551561
static int
552562
locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self)
553563
{
@@ -776,6 +786,7 @@ PyDoc_STRVAR(hashtype_doc,
776786

777787
static PyType_Slot EVPtype_slots[] = {
778788
{Py_tp_dealloc, EVP_dealloc},
789+
{Py_tp_traverse, EVP_traverse},
779790
{Py_tp_repr, EVP_repr},
780791
{Py_tp_doc, (char *)hashtype_doc},
781792
{Py_tp_methods, EVP_methods},
@@ -784,10 +795,15 @@ static PyType_Slot EVPtype_slots[] = {
784795
};
785796

786797
static PyType_Spec EVPtype_spec = {
787-
"_hashlib.HASH", /*tp_name*/
788-
sizeof(EVPobject), /*tp_basicsize*/
789-
0, /*tp_itemsize*/
790-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
798+
.name = "_hashlib.HASH",
799+
.basicsize = sizeof(EVPobject),
800+
.flags = (
801+
Py_TPFLAGS_DEFAULT
802+
| Py_TPFLAGS_BASETYPE
803+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
804+
| Py_TPFLAGS_IMMUTABLETYPE
805+
| Py_TPFLAGS_HAVE_GC
806+
),
791807
EVPtype_slots
792808
};
793809

@@ -926,18 +942,25 @@ PyDoc_STRVAR(hashxoftype_doc,
926942
"digest_size -- number of bytes in this hashes output");
927943

928944
static PyType_Slot EVPXOFtype_slots[] = {
945+
{Py_tp_dealloc, EVP_dealloc},
946+
{Py_tp_traverse, EVP_traverse},
929947
{Py_tp_doc, (char *)hashxoftype_doc},
930948
{Py_tp_methods, EVPXOF_methods},
931949
{Py_tp_getset, EVPXOF_getseters},
932950
{0, 0},
933951
};
934952

935953
static PyType_Spec EVPXOFtype_spec = {
936-
"_hashlib.HASHXOF", /*tp_name*/
937-
sizeof(EVPobject), /*tp_basicsize*/
938-
0, /*tp_itemsize*/
939-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
940-
EVPXOFtype_slots
954+
.name = "_hashlib.HASHXOF",
955+
.basicsize = sizeof(EVPobject),
956+
.flags = (
957+
Py_TPFLAGS_DEFAULT
958+
| Py_TPFLAGS_BASETYPE
959+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
960+
| Py_TPFLAGS_IMMUTABLETYPE
961+
| Py_TPFLAGS_HAVE_GC
962+
),
963+
.slots = EVPXOFtype_slots
941964
};
942965

943966

@@ -1621,7 +1644,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
16211644
}
16221645

16231646
_hashlibstate *state = get_hashlib_state(module);
1624-
self = PyObject_New(HMACobject, state->HMACtype);
1647+
assert(state->HMACtype != NULL);
1648+
self = (HMACobject *)state->HMACtype->tp_alloc(state->HMACtype, 0);
16251649
if (self == NULL) {
16261650
goto error;
16271651
}
@@ -1726,7 +1750,8 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
17261750
return NULL;
17271751
}
17281752

1729-
retval = PyObject_New(HMACobject, Py_TYPE(self));
1753+
PyTypeObject *type = Py_TYPE(self);
1754+
retval = (HMACobject *)type->tp_alloc(type, 0);
17301755
if (retval == NULL) {
17311756
HMAC_CTX_free(ctx);
17321757
return NULL;
@@ -1740,16 +1765,24 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
17401765
static void
17411766
_hmac_dealloc(PyObject *op)
17421767
{
1768+
PyTypeObject *tp = Py_TYPE(op);
1769+
PyObject_GC_UnTrack(op);
17431770
HMACobject *self = HMACobject_CAST(op);
1744-
PyTypeObject *tp = Py_TYPE(self);
17451771
if (self->ctx != NULL) {
17461772
HMAC_CTX_free(self->ctx);
17471773
self->ctx = NULL;
17481774
}
1749-
PyObject_Free(self);
1775+
tp->tp_free(self);
17501776
Py_DECREF(tp);
17511777
}
17521778

1779+
static int
1780+
_hmac_traverse(PyObject *op, visitproc visit, void *arg)
1781+
{
1782+
Py_VISIT(Py_TYPE(op));
1783+
return 0;
1784+
}
1785+
17531786
static PyObject *
17541787
_hmac_repr(PyObject *op)
17551788
{
@@ -1922,15 +1955,21 @@ static PyType_Slot HMACtype_slots[] = {
19221955
{Py_tp_doc, (char *)hmactype_doc},
19231956
{Py_tp_repr, _hmac_repr},
19241957
{Py_tp_dealloc, _hmac_dealloc},
1958+
{Py_tp_traverse, _hmac_traverse},
19251959
{Py_tp_methods, HMAC_methods},
19261960
{Py_tp_getset, HMAC_getset},
19271961
{0, NULL}
19281962
};
19291963

19301964
PyType_Spec HMACtype_spec = {
1931-
"_hashlib.HMAC", /* name */
1932-
sizeof(HMACobject), /* basicsize */
1933-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
1965+
.name = "_hashlib.HMAC",
1966+
.basicsize = sizeof(HMACobject),
1967+
.flags = (
1968+
Py_TPFLAGS_DEFAULT
1969+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
1970+
| Py_TPFLAGS_IMMUTABLETYPE
1971+
| Py_TPFLAGS_HAVE_GC
1972+
),
19341973
.slots = HMACtype_slots,
19351974
};
19361975

0 commit comments

Comments
 (0)