Skip to content

Commit 459cc57

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 459cc57

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

Modules/_hashopenssl.c

Lines changed: 49 additions & 15 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},
@@ -926,18 +937,25 @@ PyDoc_STRVAR(hashxoftype_doc,
926937
"digest_size -- number of bytes in this hashes output");
927938

928939
static PyType_Slot EVPXOFtype_slots[] = {
940+
{Py_tp_dealloc, EVP_dealloc},
941+
{Py_tp_traverse, EVP_traverse},
929942
{Py_tp_doc, (char *)hashxoftype_doc},
930943
{Py_tp_methods, EVPXOF_methods},
931944
{Py_tp_getset, EVPXOF_getseters},
932945
{0, 0},
933946
};
934947

935948
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
949+
.name = "_hashlib.HASHXOF",
950+
.basicsize = sizeof(EVPobject),
951+
.flags = (
952+
Py_TPFLAGS_DEFAULT
953+
| Py_TPFLAGS_BASETYPE
954+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
955+
| Py_TPFLAGS_IMMUTABLETYPE
956+
| Py_TPFLAGS_HAVE_GC
957+
),
958+
.slots = EVPXOFtype_slots
941959
};
942960

943961

@@ -1621,7 +1639,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj,
16211639
}
16221640

16231641
_hashlibstate *state = get_hashlib_state(module);
1624-
self = PyObject_New(HMACobject, state->HMACtype);
1642+
assert(state->HMACtype != NULL);
1643+
self = (HMACobject *)state->HMACtype->tp_alloc(state->HMACtype, 0);
16251644
if (self == NULL) {
16261645
goto error;
16271646
}
@@ -1726,7 +1745,8 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
17261745
return NULL;
17271746
}
17281747

1729-
retval = PyObject_New(HMACobject, Py_TYPE(self));
1748+
PyTypeObject *type = Py_TYPE(self);
1749+
retval = (HMACobject *)type->tp_alloc(type, 0);
17301750
if (retval == NULL) {
17311751
HMAC_CTX_free(ctx);
17321752
return NULL;
@@ -1740,16 +1760,24 @@ _hashlib_HMAC_copy_impl(HMACobject *self)
17401760
static void
17411761
_hmac_dealloc(PyObject *op)
17421762
{
1763+
PyTypeObject *tp = Py_TYPE(op);
1764+
PyObject_GC_UnTrack(op);
17431765
HMACobject *self = HMACobject_CAST(op);
1744-
PyTypeObject *tp = Py_TYPE(self);
17451766
if (self->ctx != NULL) {
17461767
HMAC_CTX_free(self->ctx);
17471768
self->ctx = NULL;
17481769
}
1749-
PyObject_Free(self);
1770+
tp->tp_free(self);
17501771
Py_DECREF(tp);
17511772
}
17521773

1774+
static int
1775+
_hmac_traverse(PyObject *op, visitproc visit, void *arg)
1776+
{
1777+
Py_VISIT(Py_TYPE(op));
1778+
return 0;
1779+
}
1780+
17531781
static PyObject *
17541782
_hmac_repr(PyObject *op)
17551783
{
@@ -1922,15 +1950,21 @@ static PyType_Slot HMACtype_slots[] = {
19221950
{Py_tp_doc, (char *)hmactype_doc},
19231951
{Py_tp_repr, _hmac_repr},
19241952
{Py_tp_dealloc, _hmac_dealloc},
1953+
{Py_tp_traverse, _hmac_traverse},
19251954
{Py_tp_methods, HMAC_methods},
19261955
{Py_tp_getset, HMAC_getset},
19271956
{0, NULL}
19281957
};
19291958

19301959
PyType_Spec HMACtype_spec = {
1931-
"_hashlib.HMAC", /* name */
1932-
sizeof(HMACobject), /* basicsize */
1933-
.flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
1960+
.name = "_hashlib.HMAC",
1961+
.basicsize = sizeof(HMACobject),
1962+
.flags = (
1963+
Py_TPFLAGS_DEFAULT
1964+
| Py_TPFLAGS_DISALLOW_INSTANTIATION
1965+
| Py_TPFLAGS_IMMUTABLETYPE
1966+
| Py_TPFLAGS_HAVE_GC
1967+
),
19341968
.slots = HMACtype_slots,
19351969
};
19361970

0 commit comments

Comments
 (0)