diff options
author | AlexSm <alex@ydb.tech> | 2024-03-05 10:40:59 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-05 12:40:59 +0300 |
commit | 1ac13c847b5358faba44dbb638a828e24369467b (patch) | |
tree | 07672b4dd3604ad3dee540a02c6494cb7d10dc3d /contrib/tools/python3/Modules/md5module.c | |
parent | ffcca3e7f7958ddc6487b91d3df8c01054bd0638 (diff) | |
download | ydb-1ac13c847b5358faba44dbb638a828e24369467b.tar.gz |
Library import 16 (#2433)
Co-authored-by: robot-piglet <robot-piglet@yandex-team.com>
Co-authored-by: deshevoy <deshevoy@yandex-team.com>
Co-authored-by: robot-contrib <robot-contrib@yandex-team.com>
Co-authored-by: thegeorg <thegeorg@yandex-team.com>
Co-authored-by: robot-ya-builder <robot-ya-builder@yandex-team.com>
Co-authored-by: svidyuk <svidyuk@yandex-team.com>
Co-authored-by: shadchin <shadchin@yandex-team.com>
Co-authored-by: robot-ratatosk <robot-ratatosk@yandex-team.com>
Co-authored-by: innokentii <innokentii@yandex-team.com>
Co-authored-by: arkady-e1ppa <arkady-e1ppa@yandex-team.com>
Co-authored-by: snermolaev <snermolaev@yandex-team.com>
Co-authored-by: dimdim11 <dimdim11@yandex-team.com>
Co-authored-by: kickbutt <kickbutt@yandex-team.com>
Co-authored-by: abdullinsaid <abdullinsaid@yandex-team.com>
Co-authored-by: korsunandrei <korsunandrei@yandex-team.com>
Co-authored-by: petrk <petrk@yandex-team.com>
Co-authored-by: miroslav2 <miroslav2@yandex-team.com>
Co-authored-by: serjflint <serjflint@yandex-team.com>
Co-authored-by: akhropov <akhropov@yandex-team.com>
Co-authored-by: prettyboy <prettyboy@yandex-team.com>
Co-authored-by: ilikepugs <ilikepugs@yandex-team.com>
Co-authored-by: hiddenpath <hiddenpath@yandex-team.com>
Co-authored-by: mikhnenko <mikhnenko@yandex-team.com>
Co-authored-by: spreis <spreis@yandex-team.com>
Co-authored-by: andreyshspb <andreyshspb@yandex-team.com>
Co-authored-by: dimaandreev <dimaandreev@yandex-team.com>
Co-authored-by: rashid <rashid@yandex-team.com>
Co-authored-by: robot-ydb-importer <robot-ydb-importer@yandex-team.com>
Co-authored-by: r-vetrov <r-vetrov@yandex-team.com>
Co-authored-by: ypodlesov <ypodlesov@yandex-team.com>
Co-authored-by: zaverden <zaverden@yandex-team.com>
Co-authored-by: vpozdyayev <vpozdyayev@yandex-team.com>
Co-authored-by: robot-cozmo <robot-cozmo@yandex-team.com>
Co-authored-by: v-korovin <v-korovin@yandex-team.com>
Co-authored-by: arikon <arikon@yandex-team.com>
Co-authored-by: khoden <khoden@yandex-team.com>
Co-authored-by: psydmm <psydmm@yandex-team.com>
Co-authored-by: robot-javacom <robot-javacom@yandex-team.com>
Co-authored-by: dtorilov <dtorilov@yandex-team.com>
Co-authored-by: sennikovmv <sennikovmv@yandex-team.com>
Co-authored-by: hcpp <hcpp@ydb.tech>
Diffstat (limited to 'contrib/tools/python3/Modules/md5module.c')
-rw-r--r-- | contrib/tools/python3/Modules/md5module.c | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/contrib/tools/python3/Modules/md5module.c b/contrib/tools/python3/Modules/md5module.c new file mode 100644 index 0000000000..2122f8b18b --- /dev/null +++ b/contrib/tools/python3/Modules/md5module.c @@ -0,0 +1,394 @@ +/* MD5 module */ + +/* This module provides an interface to the MD5 algorithm */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* MD5 objects */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" +#include "hashlib.h" +#include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() + +/*[clinic input] +module _md5 +class MD5Type "MD5object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6e5261719957a912]*/ + +/* Some useful types */ + +#if SIZEOF_INT == 4 +typedef unsigned int MD5_INT32; /* 32-bit integer */ +typedef long long MD5_INT64; /* 64-bit integer */ +#else +/* not defined. compilation will die. */ +#endif + +/* The MD5 block size and message digest sizes, in bytes */ + +#define MD5_BLOCKSIZE 64 +#define MD5_DIGESTSIZE 16 + +#include "_hacl/Hacl_Hash_MD5.h" + + +typedef struct { + PyObject_HEAD + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. + PyThread_type_lock lock; + Hacl_Streaming_MD5_state *hash_state; +} MD5object; + +#include "clinic/md5module.c.h" + + +typedef struct { + PyTypeObject* md5_type; +} MD5State; + +static inline MD5State* +md5_get_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (MD5State *)state; +} + +static MD5object * +newMD5object(MD5State * st) +{ + MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); + md5->lock = NULL; + PyObject_GC_Track(md5); + return md5; +} + +/* Internal methods for a hash object */ +static int +MD5_traverse(PyObject *ptr, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(ptr)); + return 0; +} + +static void +MD5_dealloc(MD5object *ptr) +{ + Hacl_Streaming_MD5_legacy_free(ptr->hash_state); + if (ptr->lock != NULL) { + PyThread_free_lock(ptr->lock); + } + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); +} + + +/* External methods for a hash object */ + +/*[clinic input] +MD5Type.copy + + cls: defining_class + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) +/*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ +{ + MD5State *st = _PyType_GetModuleState(cls); + + MD5object *newobj; + if ((newobj = newMD5object(st))==NULL) + return NULL; + + ENTER_HASHLIB(self); + newobj->hash_state = Hacl_Streaming_MD5_legacy_copy(self->hash_state); + LEAVE_HASHLIB(self); + return (PyObject *)newobj; +} + +/*[clinic input] +MD5Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +MD5Type_digest_impl(MD5object *self) +/*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/ +{ + unsigned char digest[MD5_DIGESTSIZE]; + ENTER_HASHLIB(self); + Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); +} + +/*[clinic input] +MD5Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +MD5Type_hexdigest_impl(MD5object *self) +/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ +{ + unsigned char digest[MD5_DIGESTSIZE]; + ENTER_HASHLIB(self); + Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); + return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); +} + +static void update(Hacl_Streaming_MD5_state *state, uint8_t *buf, Py_ssize_t len) { +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_MD5_legacy_update(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + Hacl_Streaming_MD5_legacy_update(state, buf, (uint32_t) len); +} + +/*[clinic input] +MD5Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +MD5Type_update(MD5object *self, PyObject *obj) +/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + update(self->hash_state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + update(self->hash_state, buf.buf, buf.len); + } + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef MD5_methods[] = { + MD5TYPE_COPY_METHODDEF + MD5TYPE_DIGEST_METHODDEF + MD5TYPE_HEXDIGEST_METHODDEF + MD5TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +MD5_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(MD5_BLOCKSIZE); +} + +static PyObject * +MD5_get_name(PyObject *self, void *closure) +{ + return PyUnicode_FromStringAndSize("md5", 3); +} + +static PyObject * +md5_get_digest_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(MD5_DIGESTSIZE); +} + +static PyGetSetDef MD5_getseters[] = { + {"block_size", + (getter)MD5_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)MD5_get_name, NULL, + NULL, + NULL}, + {"digest_size", + (getter)md5_get_digest_size, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot md5_type_slots[] = { + {Py_tp_dealloc, MD5_dealloc}, + {Py_tp_methods, MD5_methods}, + {Py_tp_getset, MD5_getseters}, + {Py_tp_traverse, MD5_traverse}, + {0,0} +}; + +static PyType_Spec md5_type_spec = { + .name = "_md5.md5", + .basicsize = sizeof(MD5object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = md5_type_slots +}; + +/* The single module-level function: new() */ + +/*[clinic input] +_md5.md5 + + string: object(c_default="NULL") = b'' + * + usedforsecurity: bool = True + +Return a new MD5 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) +/*[clinic end generated code: output=587071f76254a4ac input=7a144a1905636985]*/ +{ + MD5object *new; + Py_buffer buf; + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + MD5State *st = md5_get_state(module); + if ((new = newMD5object(st)) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + new->hash_state = Hacl_Streaming_MD5_legacy_create_in(); + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update(new->hash_state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update(new->hash_state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + + +/* List of functions exported by this module */ + +static struct PyMethodDef MD5_functions[] = { + _MD5_MD5_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + +static int +_md5_traverse(PyObject *module, visitproc visit, void *arg) +{ + MD5State *state = md5_get_state(module); + Py_VISIT(state->md5_type); + return 0; +} + +static int +_md5_clear(PyObject *module) +{ + MD5State *state = md5_get_state(module); + Py_CLEAR(state->md5_type); + return 0; +} + +static void +_md5_free(void *module) +{ + _md5_clear((PyObject *)module); +} + +/* Initialize this module. */ +static int +md5_exec(PyObject *m) +{ + MD5State *st = md5_get_state(m); + + st->md5_type = (PyTypeObject *)PyType_FromModuleAndSpec( + m, &md5_type_spec, NULL); + + if (st->md5_type == NULL) { + return -1; + } + + Py_INCREF((PyObject *)st->md5_type); + if (PyModule_AddObject(m, "MD5Type", (PyObject *)st->md5_type) < 0) { + Py_DECREF(st->md5_type); + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _md5_slots[] = { + {Py_mod_exec, md5_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + + +static struct PyModuleDef _md5module = { + PyModuleDef_HEAD_INIT, + .m_name = "_md5", + .m_size = sizeof(MD5State), + .m_methods = MD5_functions, + .m_slots = _md5_slots, + .m_traverse = _md5_traverse, + .m_clear = _md5_clear, + .m_free = _md5_free, +}; + +PyMODINIT_FUNC +PyInit__md5(void) +{ + return PyModuleDef_Init(&_md5module); +} |