From f1d36d8efaecd5c84cb35e35119b283f37d83c40 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 31 Jul 2018 09:50:16 +0300 Subject: bpo-33729: Fix issues with arguments parsing in hashlib. (GH-8346) * help(hashlib) didn't work because of incorrect module name in blake2b and blake2s classes. * Constructors blake2*(), sha3_*(), shake_*() and keccak_*() incorrectly accepted keyword argument "string" for binary data, but documented as accepting the "data" keyword argument. Now this parameter is positional-only. * Keyword-only parameters in blake2b() and blake2s() were not documented as keyword-only. * Default value for some parameters of blake2b() and blake2s() was None, which is not acceptable value. * The length argument for shake_*.digest() was wrapped out to 32 bits. * The argument for shake_128.digest() and shake_128.hexdigest() was not positional-only as intended. * TypeError messages for incorrect arguments in all constructors sha3_*(), shake_*() and keccak_*() incorrectly referred to sha3_224. Also made the following enhancements: * More accurately specified input and result types for strings, bytes and bytes-like objects. * Unified positional parameter names for update() and constructors. * Improved formatting. --- Modules/_sha3/clinic/sha3module.c.h | 59 +++++++----------------------- Modules/_sha3/sha3module.c | 72 +++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 80 deletions(-) (limited to 'Modules/_sha3') diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/_sha3/clinic/sha3module.c.h index a1e80b061e5..b2a896ec916 100644 --- a/Modules/_sha3/clinic/sha3module.c.h +++ b/Modules/_sha3/clinic/sha3module.c.h @@ -2,33 +2,6 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(py_sha3_new__doc__, -"sha3_224(string=None)\n" -"--\n" -"\n" -"Return a new SHA3 hash object with a hashbit length of 28 bytes."); - -static PyObject * -py_sha3_new_impl(PyTypeObject *type, PyObject *data); - -static PyObject * -py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", NULL}; - static _PyArg_Parser _parser = {"|O:sha3_224", _keywords, 0}; - PyObject *data = NULL; - - if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, - &data)) { - goto exit; - } - return_value = py_sha3_new_impl(type, data); - -exit: - return return_value; -} - PyDoc_STRVAR(_sha3_sha3_224_copy__doc__, "copy($self, /)\n" "--\n" @@ -51,7 +24,7 @@ PyDoc_STRVAR(_sha3_sha3_224_digest__doc__, "digest($self, /)\n" "--\n" "\n" -"Return the digest value as a string of binary data."); +"Return the digest value as a bytes object."); #define _SHA3_SHA3_224_DIGEST_METHODDEF \ {"digest", (PyCFunction)_sha3_sha3_224_digest, METH_NOARGS, _sha3_sha3_224_digest__doc__}, @@ -84,36 +57,33 @@ _sha3_sha3_224_hexdigest(SHA3object *self, PyObject *Py_UNUSED(ignored)) } PyDoc_STRVAR(_sha3_sha3_224_update__doc__, -"update($self, obj, /)\n" +"update($self, data, /)\n" "--\n" "\n" -"Update this hash object\'s state with the provided string."); +"Update this hash object\'s state with the provided bytes-like object."); #define _SHA3_SHA3_224_UPDATE_METHODDEF \ {"update", (PyCFunction)_sha3_sha3_224_update, METH_O, _sha3_sha3_224_update__doc__}, PyDoc_STRVAR(_sha3_shake_128_digest__doc__, -"digest($self, /, length)\n" +"digest($self, length, /)\n" "--\n" "\n" -"Return the digest value as a string of binary data."); +"Return the digest value as a bytes object."); #define _SHA3_SHAKE_128_DIGEST_METHODDEF \ - {"digest", (PyCFunction)_sha3_shake_128_digest, METH_FASTCALL|METH_KEYWORDS, _sha3_shake_128_digest__doc__}, + {"digest", (PyCFunction)_sha3_shake_128_digest, METH_O, _sha3_shake_128_digest__doc__}, static PyObject * _sha3_shake_128_digest_impl(SHA3object *self, unsigned long length); static PyObject * -_sha3_shake_128_digest(SHA3object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sha3_shake_128_digest(SHA3object *self, PyObject *arg) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {"k:digest", _keywords, 0}; unsigned long length; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &length)) { + if (!PyArg_Parse(arg, "O&:digest", _PyLong_UnsignedLong_Converter, &length)) { goto exit; } return_value = _sha3_shake_128_digest_impl(self, length); @@ -123,27 +93,24 @@ _sha3_shake_128_digest(SHA3object *self, PyObject *const *args, Py_ssize_t nargs } PyDoc_STRVAR(_sha3_shake_128_hexdigest__doc__, -"hexdigest($self, /, length)\n" +"hexdigest($self, length, /)\n" "--\n" "\n" "Return the digest value as a string of hexadecimal digits."); #define _SHA3_SHAKE_128_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)_sha3_shake_128_hexdigest, METH_FASTCALL|METH_KEYWORDS, _sha3_shake_128_hexdigest__doc__}, + {"hexdigest", (PyCFunction)_sha3_shake_128_hexdigest, METH_O, _sha3_shake_128_hexdigest__doc__}, static PyObject * _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length); static PyObject * -_sha3_shake_128_hexdigest(SHA3object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {"k:hexdigest", _keywords, 0}; unsigned long length; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &length)) { + if (!PyArg_Parse(arg, "O&:hexdigest", _PyLong_UnsignedLong_Converter, &length)) { goto exit; } return_value = _sha3_shake_128_hexdigest_impl(self, length); @@ -151,4 +118,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=a3aeb6c3b2fbd905 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bf823532a7bffe68 input=a9049054013a1b77]*/ diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c index 970ce1616e5..f5032fcb72d 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -170,21 +170,20 @@ newSHA3object(PyTypeObject *type) } -/*[clinic input] -@classmethod -_sha3.sha3_224.__new__ as py_sha3_new - string as data: object = NULL - -Return a new SHA3 hash object with a hashbit length of 28 bytes. -[clinic start generated code]*/ - static PyObject * -py_sha3_new_impl(PyTypeObject *type, PyObject *data) -/*[clinic end generated code: output=8d5c34279e69bf09 input=d7c582b950a858b6]*/ +py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { SHA3object *self = NULL; Py_buffer buf = {NULL, NULL}; HashReturn res; + PyObject *data = NULL; + + if (!_PyArg_NoKeywords(_PyType_Name(type), kwargs)) { + return NULL; + } + if (!PyArg_UnpackTuple(args, _PyType_Name(type), 0, 1, &data)) { + return NULL; + } self = newSHA3object(type); if (self == NULL) { @@ -292,12 +291,12 @@ _sha3_sha3_224_copy_impl(SHA3object *self) /*[clinic input] _sha3.sha3_224.digest -Return the digest value as a string of binary data. +Return the digest value as a bytes object. [clinic start generated code]*/ static PyObject * _sha3_sha3_224_digest_impl(SHA3object *self) -/*[clinic end generated code: output=fd531842e20b2d5b input=a5807917d219b30e]*/ +/*[clinic end generated code: output=fd531842e20b2d5b input=5b2a659536bbd248]*/ { unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; SHA3_state temp; @@ -347,20 +346,20 @@ _sha3_sha3_224_hexdigest_impl(SHA3object *self) /*[clinic input] _sha3.sha3_224.update - obj: object + data: object / -Update this hash object's state with the provided string. +Update this hash object's state with the provided bytes-like object. [clinic start generated code]*/ static PyObject * -_sha3_sha3_224_update(SHA3object *self, PyObject *obj) -/*[clinic end generated code: output=06721d55b483e0af input=be44bf0d1c279791]*/ +_sha3_sha3_224_update(SHA3object *self, PyObject *data) +/*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/ { Py_buffer buf; HashReturn res; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + GET_BUFFER_VIEW_OR_ERROUT(data, &buf); /* add new data, the function takes the length in bits not bytes */ if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { @@ -529,44 +528,49 @@ static PyGetSetDef SHA3_getseters[] = { py_sha3_new, /* tp_new */ \ } +PyDoc_STRVAR(sha3_224__doc__, +"sha3_224([data]) -> SHA3 object\n\ +\n\ +Return a new SHA3 hash object with a hashbit length of 28 bytes."); + PyDoc_STRVAR(sha3_256__doc__, -"sha3_256([string]) -> SHA3 object\n\ +"sha3_256([data]) -> SHA3 object\n\ \n\ Return a new SHA3 hash object with a hashbit length of 32 bytes."); PyDoc_STRVAR(sha3_384__doc__, -"sha3_384([string]) -> SHA3 object\n\ +"sha3_384([data]) -> SHA3 object\n\ \n\ Return a new SHA3 hash object with a hashbit length of 48 bytes."); PyDoc_STRVAR(sha3_512__doc__, -"sha3_512([string]) -> SHA3 object\n\ +"sha3_512([data]) -> SHA3 object\n\ \n\ Return a new SHA3 hash object with a hashbit length of 64 bytes."); -SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", py_sha3_new__doc__, SHA3_methods); +SHA3_TYPE(SHA3_224type, "_sha3.sha3_224", sha3_224__doc__, SHA3_methods); SHA3_TYPE(SHA3_256type, "_sha3.sha3_256", sha3_256__doc__, SHA3_methods); SHA3_TYPE(SHA3_384type, "_sha3.sha3_384", sha3_384__doc__, SHA3_methods); SHA3_TYPE(SHA3_512type, "_sha3.sha3_512", sha3_512__doc__, SHA3_methods); #ifdef PY_WITH_KECCAK PyDoc_STRVAR(keccak_224__doc__, -"keccak_224([string]) -> Keccak object\n\ +"keccak_224([data]) -> Keccak object\n\ \n\ Return a new Keccak hash object with a hashbit length of 28 bytes."); PyDoc_STRVAR(keccak_256__doc__, -"keccak_256([string]) -> Keccak object\n\ +"keccak_256([data]) -> Keccak object\n\ \n\ Return a new Keccak hash object with a hashbit length of 32 bytes."); PyDoc_STRVAR(keccak_384__doc__, -"keccak_384([string]) -> Keccak object\n\ +"keccak_384([data]) -> Keccak object\n\ \n\ Return a new Keccak hash object with a hashbit length of 48 bytes."); PyDoc_STRVAR(keccak_512__doc__, -"keccak_512([string]) -> Keccak object\n\ +"keccak_512([data]) -> Keccak object\n\ \n\ Return a new Keccak hash object with a hashbit length of 64 bytes."); @@ -624,15 +628,15 @@ _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) /*[clinic input] _sha3.shake_128.digest - length: unsigned_long(bitwise=True) - \ + length: unsigned_long + / -Return the digest value as a string of binary data. +Return the digest value as a bytes object. [clinic start generated code]*/ static PyObject * _sha3_shake_128_digest_impl(SHA3object *self, unsigned long length) -/*[clinic end generated code: output=2313605e2f87bb8f input=608c8ca80ae9d115]*/ +/*[clinic end generated code: output=2313605e2f87bb8f input=418ef6a36d2e6082]*/ { return _SHAKE_digest(self, length, 0); } @@ -641,15 +645,15 @@ _sha3_shake_128_digest_impl(SHA3object *self, unsigned long length) /*[clinic input] _sha3.shake_128.hexdigest - length: unsigned_long(bitwise=True) - \ + length: unsigned_long + / Return the digest value as a string of hexadecimal digits. [clinic start generated code]*/ static PyObject * _sha3_shake_128_hexdigest_impl(SHA3object *self, unsigned long length) -/*[clinic end generated code: output=bf8e2f1e490944a8 input=64e56b4760db4573]*/ +/*[clinic end generated code: output=bf8e2f1e490944a8 input=69fb29b0926ae321]*/ { return _SHAKE_digest(self, length, 1); } @@ -664,12 +668,12 @@ static PyMethodDef SHAKE_methods[] = { }; PyDoc_STRVAR(shake_128__doc__, -"shake_128([string]) -> SHAKE object\n\ +"shake_128([data]) -> SHAKE object\n\ \n\ Return a new SHAKE hash object."); PyDoc_STRVAR(shake_256__doc__, -"shake_256([string]) -> SHAKE object\n\ +"shake_256([data]) -> SHAKE object\n\ \n\ Return a new SHAKE hash object."); -- cgit v1.2.3-65-gdbad