Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5c79e13

Browse files
committed
fully implement GC protocol for _hashlib objects
1 parent 31d3836 commit 5c79e13

1 file changed

Lines changed: 39 additions & 10 deletions

File tree

Modules/_hashopenssl.c

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ 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+
HASHobject *retval = PyObject_GC_New(HASHobject, type);
756756
if (retval == NULL) {
757757
return NULL;
758758
}
@@ -764,6 +764,7 @@ new_hash_object(PyTypeObject *type)
764764
return NULL;
765765
}
766766

767+
PyObject_GC_Track(retval);
767768
return retval;
768769
}
769770

@@ -792,13 +793,21 @@ _hashlib_HASH_hash(HASHobject *self, const void *vp, Py_ssize_t len)
792793
static void
793794
_hashlib_HASH_dealloc(PyObject *op)
794795
{
796+
PyTypeObject *tp = Py_TYPE(op);
797+
PyObject_GC_UnTrack(op);
795798
HASHobject *self = HASHobject_CAST(op);
796-
PyTypeObject *tp = Py_TYPE(self);
797799
EVP_MD_CTX_free(self->ctx);
798-
PyObject_Free(self);
800+
PyObject_GC_Del(self);
799801
Py_DECREF(tp);
800802
}
801803

804+
static int
805+
_hashlib_HASH_traverse(PyObject *op, visitproc visit, void *arg)
806+
{
807+
Py_VISIT(Py_TYPE(op));
808+
return 0;
809+
}
810+
802811
static int
803812
_hashlib_HASH_copy_locked(HASHobject *self, EVP_MD_CTX *new_ctx_p)
804813
{
@@ -993,6 +1002,7 @@ PyDoc_STRVAR(HASHobject_type_doc,
9931002

9941003
static PyType_Slot HASHobject_type_slots[] = {
9951004
{Py_tp_dealloc, _hashlib_HASH_dealloc},
1005+
{Py_tp_traverse, _hashlib_HASH_traverse},
9961006
{Py_tp_repr, _hashlib_HASH_repr},
9971007
{Py_tp_doc, (char *)HASHobject_type_doc},
9981008
{Py_tp_methods, HASH_methods},
@@ -1008,6 +1018,7 @@ static PyType_Spec HASHobject_type_spec = {
10081018
| Py_TPFLAGS_BASETYPE
10091019
| Py_TPFLAGS_DISALLOW_INSTANTIATION
10101020
| Py_TPFLAGS_IMMUTABLETYPE
1021+
| Py_TPFLAGS_HAVE_GC
10111022
),
10121023
.slots = HASHobject_type_slots
10131024
};
@@ -1165,6 +1176,7 @@ PyDoc_STRVAR(HASHXOFobject_type_doc,
11651176
"digest_size -- number of bytes in this hashes output");
11661177

11671178
static PyType_Slot HASHXOFobject_type_slots[] = {
1179+
/* tp_dealloc and tp_traverse are inherited from _hashlib.HASH */
11681180
{Py_tp_doc, (char *)HASHXOFobject_type_doc},
11691181
{Py_tp_methods, HASHXOFobject_methods},
11701182
{Py_tp_getset, HASHXOFobject_getsets},
@@ -1179,6 +1191,7 @@ static PyType_Spec HASHXOFobject_type_spec = {
11791191
| Py_TPFLAGS_BASETYPE
11801192
| Py_TPFLAGS_DISALLOW_INSTANTIATION
11811193
| Py_TPFLAGS_IMMUTABLETYPE
1194+
| Py_TPFLAGS_HAVE_GC
11821195
),
11831196
.slots = HASHXOFobject_type_slots
11841197
};
@@ -1902,14 +1915,15 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
19021915
goto error;
19031916
}
19041917

1905-
self = PyObject_New(HMACobject, state->HMAC_type);
1918+
self = PyObject_GC_New(HMACobject, state->HMAC_type);
19061919
if (self == NULL) {
19071920
goto error;
19081921
}
19091922

19101923
self->ctx = ctx;
19111924
ctx = NULL; // 'ctx' is now owned by 'self'
19121925
HASHLIB_INIT_MUTEX(self);
1926+
PyObject_GC_Track(self);
19131927

19141928
if ((msg_obj != NULL) && (msg_obj != Py_None)) {
19151929
if (!_hmac_update(self, msg_obj)) {
@@ -2008,30 +2022,39 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
20082022
return NULL;
20092023
}
20102024

2011-
retval = PyObject_New(HMACobject, Py_TYPE(self));
2025+
retval = PyObject_GC_New(HMACobject, Py_TYPE(self));
20122026
if (retval == NULL) {
20132027
HMAC_CTX_free(ctx);
20142028
return NULL;
20152029
}
20162030
retval->ctx = ctx;
20172031
HASHLIB_INIT_MUTEX(retval);
20182032

2033+
PyObject_GC_Track(retval);
20192034
return (PyObject *)retval;
20202035
}
20212036

20222037
static void
20232038
_hmac_dealloc(PyObject *op)
20242039
{
2040+
PyTypeObject *tp = Py_TYPE(op);
2041+
PyObject_GC_UnTrack(op);
20252042
HMACobject *self = HMACobject_CAST(op);
2026-
PyTypeObject *tp = Py_TYPE(self);
20272043
if (self->ctx != NULL) {
20282044
HMAC_CTX_free(self->ctx);
20292045
self->ctx = NULL;
20302046
}
2031-
PyObject_Free(self);
2047+
PyObject_GC_Del(self);
20322048
Py_DECREF(tp);
20332049
}
20342050

2051+
static int
2052+
_hashlib_HMAC_traverse(PyObject *op, visitproc visit, void *arg)
2053+
{
2054+
Py_VISIT(Py_TYPE(op));
2055+
return 0;
2056+
}
2057+
20352058
static PyObject *
20362059
_hmac_repr(PyObject *op)
20372060
{
@@ -2198,15 +2221,21 @@ static PyType_Slot HMACtype_slots[] = {
21982221
{Py_tp_doc, (char *)hmactype_doc},
21992222
{Py_tp_repr, _hmac_repr},
22002223
{Py_tp_dealloc, _hmac_dealloc},
2224+
{Py_tp_traverse, _hashlib_HMAC_traverse},
22012225
{Py_tp_methods, HMAC_methods},
22022226
{Py_tp_getset, HMAC_getset},
22032227
{0, NULL}
22042228
};
22052229

22062230
PyType_Spec HMACtype_spec = {
2207-
"_hashlib.HMAC", /* name */
2208-
sizeof(HMACobject), /* basicsize */
2209-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
2231+
.name = "_hashlib.HMAC",
2232+
.basicsize = sizeof(HMACobject),
2233+
.flags = (
2234+
Py_TPFLAGS_DEFAULT
2235+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
2236+
| Py_TPFLAGS_IMMUTABLETYPE
2237+
| Py_TPFLAGS_HAVE_GC
2238+
),
22102239
.slots = HMACtype_slots,
22112240
};
22122241

0 commit comments

Comments
 (0)