Skip to content

Commit f543e18

Browse files
[3.6] bpo-33729: Fix issues with arguments parsing in hashlib. (GH-8346) (GH-8581) (GH-9657)
* 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. (cherry picked from commit f1d36d8) (cherry picked from commit 47957da)
1 parent 3baee3b commit f543e18

File tree

11 files changed

+219
-267
lines changed

11 files changed

+219
-267
lines changed

Doc/library/hashlib.rst

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ More condensed:
101101

102102
.. function:: new(name[, data])
103103

104-
Is a generic constructor that takes the string name of the desired
104+
Is a generic constructor that takes the string *name* of the desired
105105
algorithm as its first parameter. It also exists to allow access to the
106106
above listed hashes as well as any other algorithms that your OpenSSL
107107
library may offer. The named constructors are much faster than :func:`new`
@@ -162,10 +162,10 @@ A hash object has the following attributes:
162162
A hash object has the following methods:
163163

164164

165-
.. method:: hash.update(arg)
165+
.. method:: hash.update(data)
166166

167-
Update the hash object with the object *arg*, which must be interpretable as
168-
a buffer of bytes. Repeated calls are equivalent to a single call with the
167+
Update the hash object with the :term:`bytes-like object`.
168+
Repeated calls are equivalent to a single call with the
169169
concatenation of all the arguments: ``m.update(a); m.update(b)`` is
170170
equivalent to ``m.update(a+b)``.
171171

@@ -206,7 +206,7 @@ by the SHAKE algorithm.
206206
.. method:: shake.digest(length)
207207

208208
Return the digest of the data passed to the :meth:`update` method so far.
209-
This is a bytes object of size ``length`` which may contain bytes in
209+
This is a bytes object of size *length* which may contain bytes in
210210
the whole range from 0 to 255.
211211

212212

@@ -262,9 +262,10 @@ include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_.
262262
The function provides scrypt password-based key derivation function as
263263
defined in :rfc:`7914`.
264264

265-
*password* and *salt* must be bytes-like objects. Applications and
266-
libraries should limit *password* to a sensible length (e.g. 1024). *salt*
267-
should be about 16 or more bytes from a proper source, e.g. :func:`os.urandom`.
265+
*password* and *salt* must be :term:`bytes-like objects
266+
<bytes-like object>`. Applications and libraries should limit *password*
267+
to a sensible length (e.g. 1024). *salt* should be about 16 or more
268+
bytes from a proper source, e.g. :func:`os.urandom`.
268269

269270
*n* is the CPU/Memory cost factor, *r* the block size, *p* parallelization
270271
factor and *maxmem* limits memory (OpenSSL 1.1.0 defaults to 32 MB).
@@ -305,20 +306,20 @@ Creating hash objects
305306
New hash objects are created by calling constructor functions:
306307

307308

308-
.. function:: blake2b(data=b'', digest_size=64, key=b'', salt=b'', \
309+
.. function:: blake2b(data=b'', *, digest_size=64, key=b'', salt=b'', \
309310
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
310311
node_depth=0, inner_size=0, last_node=False)
311312

312-
.. function:: blake2s(data=b'', digest_size=32, key=b'', salt=b'', \
313+
.. function:: blake2s(data=b'', *, digest_size=32, key=b'', salt=b'', \
313314
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
314315
node_depth=0, inner_size=0, last_node=False)
315316

316317

317318
These functions return the corresponding hash objects for calculating
318319
BLAKE2b or BLAKE2s. They optionally take these general parameters:
319320

320-
* *data*: initial chunk of data to hash, which must be interpretable as buffer
321-
of bytes.
321+
* *data*: initial chunk of data to hash, which must be
322+
:term:`bytes-like object`. It can be passed only as positional argument.
322323

323324
* *digest_size*: size of output digest in bytes.
324325

@@ -427,7 +428,7 @@ object, and, finally, get the digest out of the object by calling
427428

428429

429430
As a shortcut, you can pass the first chunk of data to update directly to the
430-
constructor as the first argument (or as *data* keyword argument):
431+
constructor as the positional argument:
431432

432433
>>> from hashlib import blake2b
433434
>>> blake2b(b'Hello world').hexdigest()

Lib/hashlib.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@
2525
sha384 and sha512 will be slow on 32 bit platforms.
2626
2727
Hash objects have these methods:
28-
- update(arg): Update the hash object with the bytes in arg. Repeated calls
29-
are equivalent to a single call with the concatenation of all
30-
the arguments.
31-
- digest(): Return the digest of the bytes passed to the update() method
32-
so far.
33-
- hexdigest(): Like digest() except the digest is returned as a unicode
34-
object of double length, containing only hexadecimal digits.
35-
- copy(): Return a copy (clone) of the hash object. This can be used to
36-
efficiently compute the digests of strings that share a common
37-
initial substring.
38-
39-
For example, to obtain the digest of the string 'Nobody inspects the
28+
- update(data): Update the hash object with the bytes in data. Repeated calls
29+
are equivalent to a single call with the concatenation of all
30+
the arguments.
31+
- digest(): Return the digest of the bytes passed to the update() method
32+
so far as a bytes object.
33+
- hexdigest(): Like digest() except the digest is returned as a string
34+
of double length, containing only hexadecimal digits.
35+
- copy(): Return a copy (clone) of the hash object. This can be used to
36+
efficiently compute the digests of datas that share a common
37+
initial substring.
38+
39+
For example, to obtain the digest of the byte string 'Nobody inspects the
4040
spammish repetition':
4141
4242
>>> import hashlib
@@ -130,14 +130,15 @@ def __get_openssl_constructor(name):
130130

131131
def __py_new(name, data=b'', **kwargs):
132132
"""new(name, data=b'', **kwargs) - Return a new hashing object using the
133-
named algorithm; optionally initialized with data (which must be bytes).
133+
named algorithm; optionally initialized with data (which must be
134+
a bytes-like object).
134135
"""
135136
return __get_builtin_constructor(name)(data, **kwargs)
136137

137138

138139
def __hash_new(name, data=b'', **kwargs):
139140
"""new(name, data=b'') - Return a new hashing object using the named algorithm;
140-
optionally initialized with data (which must be bytes).
141+
optionally initialized with data (which must be a bytes-like object).
141142
"""
142143
if name in {'blake2b', 'blake2s'}:
143144
# Prefer our blake2 implementation.

Lib/test/test_hashlib.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,8 +571,12 @@ def check_blake2(self, constructor, salt_size, person_size, key_size,
571571
self.assertRaises(OverflowError, constructor, node_offset=-1)
572572
self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)
573573

574+
self.assertRaises(TypeError, constructor, data=b'')
575+
self.assertRaises(TypeError, constructor, string=b'')
576+
self.assertRaises(TypeError, constructor, '')
577+
574578
constructor(
575-
string=b'',
579+
b'',
576580
key=b'',
577581
salt=b'',
578582
person=b'',
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed issues with arguments parsing in :mod:`hashlib`.

Modules/_blake2/blake2b_impl.c

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ typedef struct {
4949
#include "clinic/blake2b_impl.c.h"
5050

5151
/*[clinic input]
52-
module _blake2b
53-
class _blake2b.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
52+
module _blake2
53+
class _blake2.blake2b "BLAKE2bObject *" "&PyBlake2_BLAKE2bType"
5454
[clinic start generated code]*/
55-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6893358c6622aecf]*/
55+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d47b0527b39c673f]*/
5656

5757

5858
static BLAKE2bObject *
@@ -70,17 +70,18 @@ new_BLAKE2bObject(PyTypeObject *type)
7070

7171
/*[clinic input]
7272
@classmethod
73-
_blake2b.blake2b.__new__ as py_blake2b_new
74-
string as data: object = NULL
73+
_blake2.blake2b.__new__ as py_blake2b_new
74+
data: object(c_default="NULL") = b''
75+
/
7576
*
76-
digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2b.blake2b.MAX_DIGEST_SIZE
77-
key: Py_buffer = None
78-
salt: Py_buffer = None
79-
person: Py_buffer = None
77+
digest_size: int(c_default="BLAKE2B_OUTBYTES") = _blake2.blake2b.MAX_DIGEST_SIZE
78+
key: Py_buffer(c_default="NULL", py_default="b''") = None
79+
salt: Py_buffer(c_default="NULL", py_default="b''") = None
80+
person: Py_buffer(c_default="NULL", py_default="b''") = None
8081
fanout: int = 1
8182
depth: int = 1
82-
leaf_size as leaf_size_obj: object = NULL
83-
node_offset as node_offset_obj: object = NULL
83+
leaf_size as leaf_size_obj: object(c_default="NULL") = 0
84+
node_offset as node_offset_obj: object(c_default="NULL") = 0
8485
node_depth: int = 0
8586
inner_size: int = 0
8687
last_node: bool = False
@@ -94,7 +95,7 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
9495
int fanout, int depth, PyObject *leaf_size_obj,
9596
PyObject *node_offset_obj, int node_depth,
9697
int inner_size, int last_node)
97-
/*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/
98+
/*[clinic end generated code: output=7506d8d890e5f13b input=aca35b33c5612b4b]*/
9899
{
99100
BLAKE2bObject *self = NULL;
100101
Py_buffer buf;
@@ -256,14 +257,14 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
256257
}
257258

258259
/*[clinic input]
259-
_blake2b.blake2b.copy
260+
_blake2.blake2b.copy
260261
261262
Return a copy of the hash object.
262263
[clinic start generated code]*/
263264

264265
static PyObject *
265-
_blake2b_blake2b_copy_impl(BLAKE2bObject *self)
266-
/*[clinic end generated code: output=c89cd33550ab1543 input=4c9c319f18f10747]*/
266+
_blake2_blake2b_copy_impl(BLAKE2bObject *self)
267+
/*[clinic end generated code: output=ff6acee5f93656ae input=e383c2d199fd8a2e]*/
267268
{
268269
BLAKE2bObject *cpy;
269270

@@ -278,21 +279,21 @@ _blake2b_blake2b_copy_impl(BLAKE2bObject *self)
278279
}
279280

280281
/*[clinic input]
281-
_blake2b.blake2b.update
282+
_blake2.blake2b.update
282283
283-
obj: object
284+
data: object
284285
/
285286
286-
Update this hash object's state with the provided string.
287+
Update this hash object's state with the provided bytes-like object.
287288
[clinic start generated code]*/
288289

289290
static PyObject *
290-
_blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
291-
/*[clinic end generated code: output=a888f07c4cddbe94 input=3ecb8c13ee4260f2]*/
291+
_blake2_blake2b_update(BLAKE2bObject *self, PyObject *data)
292+
/*[clinic end generated code: output=010dfcbe22654359 input=ffc4aa6a6a225d31]*/
292293
{
293294
Py_buffer buf;
294295

295-
GET_BUFFER_VIEW_OR_ERROUT(obj, &buf);
296+
GET_BUFFER_VIEW_OR_ERROUT(data, &buf);
296297

297298
#ifdef WITH_THREAD
298299
if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE)
@@ -317,14 +318,14 @@ _blake2b_blake2b_update(BLAKE2bObject *self, PyObject *obj)
317318
}
318319

319320
/*[clinic input]
320-
_blake2b.blake2b.digest
321+
_blake2.blake2b.digest
321322
322-
Return the digest value as a string of binary data.
323+
Return the digest value as a bytes object.
323324
[clinic start generated code]*/
324325

325326
static PyObject *
326-
_blake2b_blake2b_digest_impl(BLAKE2bObject *self)
327-
/*[clinic end generated code: output=b13a79360d984740 input=ac2fa462ebb1b9c7]*/
327+
_blake2_blake2b_digest_impl(BLAKE2bObject *self)
328+
/*[clinic end generated code: output=a5864660f4bfc61a input=7d21659e9c5fff02]*/
328329
{
329330
uint8_t digest[BLAKE2B_OUTBYTES];
330331
blake2b_state state_cpy;
@@ -338,14 +339,14 @@ _blake2b_blake2b_digest_impl(BLAKE2bObject *self)
338339
}
339340

340341
/*[clinic input]
341-
_blake2b.blake2b.hexdigest
342+
_blake2.blake2b.hexdigest
342343
343344
Return the digest value as a string of hexadecimal digits.
344345
[clinic start generated code]*/
345346

346347
static PyObject *
347-
_blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self)
348-
/*[clinic end generated code: output=6a503611715b24bd input=d58f0b2f37812e33]*/
348+
_blake2_blake2b_hexdigest_impl(BLAKE2bObject *self)
349+
/*[clinic end generated code: output=b5598a87d8794a60 input=76930f6946351f56]*/
349350
{
350351
uint8_t digest[BLAKE2B_OUTBYTES];
351352
blake2b_state state_cpy;
@@ -359,10 +360,10 @@ _blake2b_blake2b_hexdigest_impl(BLAKE2bObject *self)
359360

360361

361362
static PyMethodDef py_blake2b_methods[] = {
362-
_BLAKE2B_BLAKE2B_COPY_METHODDEF
363-
_BLAKE2B_BLAKE2B_DIGEST_METHODDEF
364-
_BLAKE2B_BLAKE2B_HEXDIGEST_METHODDEF
365-
_BLAKE2B_BLAKE2B_UPDATE_METHODDEF
363+
_BLAKE2_BLAKE2B_COPY_METHODDEF
364+
_BLAKE2_BLAKE2B_DIGEST_METHODDEF
365+
_BLAKE2_BLAKE2B_HEXDIGEST_METHODDEF
366+
_BLAKE2_BLAKE2B_UPDATE_METHODDEF
366367
{NULL, NULL}
367368
};
368369

0 commit comments

Comments
 (0)