diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 5e4783395f4f48..ede9ca683adf2f 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -282,6 +282,8 @@ typedef struct { PyMutex mutex; /* OpenSSL context lock */ } EVPobject; +#define EVPobject_CAST(op) ((EVPobject *)(op)) + typedef struct { PyObject_HEAD HMAC_CTX *ctx; /* OpenSSL hmac context */ @@ -290,6 +292,8 @@ typedef struct { PyMutex mutex; /* HMAC context lock */ } HMACobject; +#define HMACobject_CAST(op) ((HMACobject *)(op)) + #include "clinic/_hashopenssl.c.h" /*[clinic input] module _hashlib @@ -497,7 +501,9 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type static EVPobject * newEVPobject(PyTypeObject *type) { - EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, type); + assert(type != NULL); + assert(type->tp_alloc != NULL); + EVPobject *retval = (EVPobject *)type->tp_alloc(type, 0); if (retval == NULL) { return NULL; } @@ -536,14 +542,23 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) /* Internal methods for a hash object */ static void -EVP_dealloc(EVPobject *self) +EVP_dealloc(PyObject *op) { - PyTypeObject *tp = Py_TYPE(self); + PyTypeObject *tp = Py_TYPE(op); + PyObject_GC_UnTrack(op); + EVPobject *self = EVPobject_CAST(op); EVP_MD_CTX_free(self->ctx); - PyObject_Free(self); + tp->tp_free(self); Py_DECREF(tp); } +static int +EVP_traverse(PyObject *op, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(op)); + return 0; +} + static int locked_EVP_MD_CTX_copy(EVP_MD_CTX *new_ctx_p, EVPobject *self) { @@ -781,6 +796,7 @@ PyDoc_STRVAR(hashtype_doc, static PyType_Slot EVPtype_slots[] = { {Py_tp_dealloc, EVP_dealloc}, + {Py_tp_traverse, EVP_traverse}, {Py_tp_repr, EVP_repr}, {Py_tp_doc, (char *)hashtype_doc}, {Py_tp_methods, EVP_methods}, @@ -789,11 +805,16 @@ static PyType_Slot EVPtype_slots[] = { }; static PyType_Spec EVPtype_spec = { - "_hashlib.HASH", /*tp_name*/ - sizeof(EVPobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, - EVPtype_slots + .name = "_hashlib.HASH", + .basicsize = sizeof(EVPobject), + .flags = ( + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION + | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_HAVE_GC + ), + .slots = EVPtype_slots }; #ifdef PY_OPENSSL_HAS_SHAKE @@ -934,6 +955,8 @@ PyDoc_STRVAR(hashxoftype_doc, "digest_size -- number of bytes in this hashes output"); static PyType_Slot EVPXOFtype_slots[] = { + {Py_tp_dealloc, EVP_dealloc}, + {Py_tp_traverse, EVP_traverse}, {Py_tp_doc, (char *)hashxoftype_doc}, {Py_tp_methods, EVPXOF_methods}, {Py_tp_getset, EVPXOF_getseters}, @@ -941,11 +964,16 @@ static PyType_Slot EVPXOFtype_slots[] = { }; static PyType_Spec EVPXOFtype_spec = { - "_hashlib.HASHXOF", /*tp_name*/ - sizeof(EVPobject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, - EVPXOFtype_slots + .name = "_hashlib.HASHXOF", + .basicsize = sizeof(EVPobject), + .flags = ( + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_BASETYPE + | Py_TPFLAGS_DISALLOW_INSTANTIATION + | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_HAVE_GC + ), + .slots = EVPXOFtype_slots }; @@ -1659,7 +1687,8 @@ _hashlib_hmac_new_impl(PyObject *module, Py_buffer *key, PyObject *msg_obj, } _hashlibstate *state = get_hashlib_state(module); - self = PyObject_New(HMACobject, state->HMACtype); + assert(state->HMACtype != NULL); + self = (HMACobject *)state->HMACtype->tp_alloc(state->HMACtype, 0); if (self == NULL) { goto error; } @@ -1764,7 +1793,8 @@ _hashlib_HMAC_copy_impl(HMACobject *self) return NULL; } - retval = PyObject_New(HMACobject, Py_TYPE(self)); + PyTypeObject *type = Py_TYPE(self); + retval = (HMACobject *)type->tp_alloc(type, 0); if (retval == NULL) { HMAC_CTX_free(ctx); return NULL; @@ -1776,17 +1806,26 @@ _hashlib_HMAC_copy_impl(HMACobject *self) } static void -_hmac_dealloc(HMACobject *self) +_hmac_dealloc(PyObject *op) { - PyTypeObject *tp = Py_TYPE(self); + PyTypeObject *tp = Py_TYPE(op); + PyObject_GC_UnTrack(op); + HMACobject *self = HMACobject_CAST(op); if (self->ctx != NULL) { HMAC_CTX_free(self->ctx); self->ctx = NULL; } - PyObject_Free(self); + tp->tp_free(self); Py_DECREF(tp); } +static int +_hmac_traverse(PyObject *op, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(op)); + return 0; +} + static PyObject * _hmac_repr(HMACobject *self) { @@ -1954,16 +1993,22 @@ digest_size -- number of bytes in digest() output\n"); static PyType_Slot HMACtype_slots[] = { {Py_tp_doc, (char *)hmactype_doc}, {Py_tp_repr, (reprfunc)_hmac_repr}, - {Py_tp_dealloc,(destructor)_hmac_dealloc}, + {Py_tp_dealloc, _hmac_dealloc}, + {Py_tp_traverse, _hmac_traverse}, {Py_tp_methods, HMAC_methods}, {Py_tp_getset, HMAC_getset}, {0, NULL} }; PyType_Spec HMACtype_spec = { - "_hashlib.HMAC", /* name */ - sizeof(HMACobject), /* basicsize */ - .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE, + .name = "_hashlib.HMAC", + .basicsize = sizeof(HMACobject), + .flags = ( + Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_DISALLOW_INSTANTIATION + | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_HAVE_GC + ), .slots = HMACtype_slots, };