Skip to content

Commit 6f1dd95

Browse files
authored
gh-116946: fully implement GC protocol for _hashlib objects (#138289)
1 parent 3ea16f9 commit 6f1dd95

File tree

1 file changed

+41
-10
lines changed

1 file changed

+41
-10
lines changed

Modules/_hashopenssl.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,9 @@ py_wrapper_EVP_MD_CTX_new(void)
752752
static HASHobject *
753753
new_hash_object(PyTypeObject *type)
754754
{
755-
HASHobject *retval = PyObject_New(HASHobject, type);
755+
assert(type != NULL);
756+
assert(type->tp_alloc != NULL);
757+
HASHobject *retval = (HASHobject *)type->tp_alloc(type, 0);
756758
if (retval == NULL) {
757759
return NULL;
758760
}
@@ -792,13 +794,21 @@ _hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len)
792794
static void
793795
_hashlib_HASH_dealloc(PyObject *op)
794796
{
797+
PyTypeObject *tp = Py_TYPE(op);
798+
PyObject_GC_UnTrack(op);
795799
HASHobject *self = HASHobject_CAST(op);
796-
PyTypeObject *tp = Py_TYPE(self);
797800
EVP_MD_CTX_free(self->ctx);
798-
PyObject_Free(self);
801+
tp->tp_free(self);
799802
Py_DECREF(tp);
800803
}
801804

805+
static int
806+
_hashlib_HASH_traverse(PyObject *op, visitproc visit, void *arg)
807+
{
808+
Py_VISIT(Py_TYPE(op));
809+
return 0;
810+
}
811+
802812
static int
803813
_hashlib_HASH_copy_locked(HASHobject *self, EVP_MD_CTX *new_ctx_p)
804814
{
@@ -993,6 +1003,7 @@ PyDoc_STRVAR(HASHobject_type_doc,
9931003

9941004
static PyType_Slot HASHobject_type_slots[] = {
9951005
{Py_tp_dealloc, _hashlib_HASH_dealloc},
1006+
{Py_tp_traverse, _hashlib_HASH_traverse},
9961007
{Py_tp_repr, _hashlib_HASH_repr},
9971008
{Py_tp_doc, (char *)HASHobject_type_doc},
9981009
{Py_tp_methods, HASH_methods},
@@ -1008,6 +1019,7 @@ static PyType_Spec HASHobject_type_spec = {
10081019
| Py_TPFLAGS_BASETYPE
10091020
| Py_TPFLAGS_DISALLOW_INSTANTIATION
10101021
| Py_TPFLAGS_IMMUTABLETYPE
1022+
| Py_TPFLAGS_HAVE_GC
10111023
),
10121024
.slots = HASHobject_type_slots
10131025
};
@@ -1165,6 +1177,8 @@ PyDoc_STRVAR(HASHXOFobject_type_doc,
11651177
"digest_size -- number of bytes in this hashes output");
11661178

11671179
static PyType_Slot HASHXOFobject_type_slots[] = {
1180+
{Py_tp_dealloc, _hashlib_HASH_dealloc},
1181+
{Py_tp_traverse, _hashlib_HASH_traverse},
11681182
{Py_tp_doc, (char *)HASHXOFobject_type_doc},
11691183
{Py_tp_methods, HASHXOFobject_methods},
11701184
{Py_tp_getset, HASHXOFobject_getsets},
@@ -1179,6 +1193,7 @@ static PyType_Spec HASHXOFobject_type_spec = {
11791193
| Py_TPFLAGS_BASETYPE
11801194
| Py_TPFLAGS_DISALLOW_INSTANTIATION
11811195
| Py_TPFLAGS_IMMUTABLETYPE
1196+
| Py_TPFLAGS_HAVE_GC
11821197
),
11831198
.slots = HASHXOFobject_type_slots
11841199
};
@@ -1902,7 +1917,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
19021917
goto error;
19031918
}
19041919

1905-
self = PyObject_New(HMACobject, state->HMAC_type);
1920+
assert(state->HMAC_type != NULL);
1921+
self = (HMACobject *)state->HMAC_type->tp_alloc(state->HMAC_type, 0);
19061922
if (self == NULL) {
19071923
goto error;
19081924
}
@@ -2008,7 +2024,8 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
20082024
return NULL;
20092025
}
20102026

2011-
retval = PyObject_New(HMACobject, Py_TYPE(self));
2027+
PyTypeObject *type = Py_TYPE(self);
2028+
retval = (HMACobject *)type->tp_alloc(type, 0);
20122029
if (retval == NULL) {
20132030
HMAC_CTX_free(ctx);
20142031
return NULL;
@@ -2022,16 +2039,24 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
20222039
static void
20232040
_hmac_dealloc(PyObject *op)
20242041
{
2042+
PyTypeObject *tp = Py_TYPE(op);
2043+
PyObject_GC_UnTrack(op);
20252044
HMACobject *self = HMACobject_CAST(op);
2026-
PyTypeObject *tp = Py_TYPE(self);
20272045
if (self->ctx != NULL) {
20282046
HMAC_CTX_free(self->ctx);
20292047
self->ctx = NULL;
20302048
}
2031-
PyObject_Free(self);
2049+
tp->tp_free(self);
20322050
Py_DECREF(tp);
20332051
}
20342052

2053+
static int
2054+
_hashlib_HMAC_traverse(PyObject *op, visitproc visit, void *arg)
2055+
{
2056+
Py_VISIT(Py_TYPE(op));
2057+
return 0;
2058+
}
2059+
20352060
static PyObject *
20362061
_hmac_repr(PyObject *op)
20372062
{
@@ -2198,15 +2223,21 @@ static PyType_Slot HMACtype_slots[] = {
21982223
{Py_tp_doc, (char *)hmactype_doc},
21992224
{Py_tp_repr, _hmac_repr},
22002225
{Py_tp_dealloc, _hmac_dealloc},
2226+
{Py_tp_traverse, _hashlib_HMAC_traverse},
22012227
{Py_tp_methods, HMAC_methods},
22022228
{Py_tp_getset, HMAC_getset},
22032229
{0, NULL}
22042230
};
22052231

22062232
PyType_Spec HMACtype_spec = {
2207-
"_hashlib.HMAC", /* name */
2208-
sizeof(HMACobject), /* basicsize */
2209-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
2233+
.name = "_hashlib.HMAC",
2234+
.basicsize = sizeof(HMACobject),
2235+
.flags = (
2236+
Py_TPFLAGS_DEFAULT
2237+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
2238+
| Py_TPFLAGS_IMMUTABLETYPE
2239+
| Py_TPFLAGS_HAVE_GC
2240+
),
22102241
.slots = HMACtype_slots,
22112242
};
22122243

0 commit comments

Comments
 (0)