gh-136787: improve exception messages for invalid hash algorithms (#1… · wrongnull/cpython@6be49ee · GitHub
Skip to content

Commit 6be49ee

Browse files
authored
pythongh-136787: improve exception messages for invalid hash algorithms (python#136802)
1 parent 800d37f commit 6be49ee

8 files changed

Lines changed: 198 additions & 48 deletions

File tree

Lib/hashlib.py

Lines changed: 11 additions & 1 deletion

Lib/hmac.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626
digest_size = None
2727

2828

29+
def _is_shake_constructor(digest_like):
30+
if isinstance(digest_like, str):
31+
name = digest_like
32+
else:
33+
h = digest_like() if callable(digest_like) else digest_like.new()
34+
if not isinstance(name := getattr(h, "name", None), str):
35+
return False
36+
return name.startswith(("shake", "SHAKE"))
37+
38+
2939
def _get_digest_constructor(digest_like):
3040
if callable(digest_like):
3141
return digest_like
@@ -109,6 +119,8 @@ def _init_old(self, key, msg, digestmod):
109119
import warnings
110120

111121
digest_cons = _get_digest_constructor(digestmod)
122+
if _is_shake_constructor(digest_cons):
123+
raise ValueError(f"unsupported hash algorithm {digestmod}")
112124

113125
self._hmac = None
114126
self._outer = digest_cons()
@@ -243,6 +255,8 @@ def digest(key, msg, digest):
243255

244256
def _compute_digest_fallback(key, msg, digest):
245257
digest_cons = _get_digest_constructor(digest)
258+
if _is_shake_constructor(digest_cons):
259+
raise ValueError(f"unsupported hash algorithm {digest}")
246260
inner = digest_cons()
247261
outer = digest_cons()
248262
blocksize = getattr(inner, 'block_size', 64)

Lib/test/test_hashlib.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ def test_clinic_signature_errors(self):
343343

344344
def test_unknown_hash(self):
345345
self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam')
346-
self.assertRaises(TypeError, hashlib.new, 1)
346+
# ensure that the exception message remains consistent
347+
err = re.escape("new() argument 'name' must be str, not int")
348+
self.assertRaisesRegex(TypeError, err, hashlib.new, 1)
347349

348350
def test_new_upper_to_lower(self):
349351
self.assertEqual(hashlib.new("SHA256").name, "sha256")
@@ -370,7 +372,9 @@ def test_get_builtin_constructor(self):
370372
sys.modules['_md5'] = _md5
371373
else:
372374
del sys.modules['_md5']
373-
self.assertRaises(TypeError, get_builtin_constructor, 3)
375+
# ensure that the exception message remains consistent
376+
err = re.escape("new() argument 'name' must be str, not int")
377+
self.assertRaises(TypeError, err, get_builtin_constructor, 3)
374378
constructor = get_builtin_constructor('md5')
375379
self.assertIs(constructor, _md5.md5)
376380
self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5'])

Lib/test/test_hmac.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ def raiser():
960960
with self.assertRaisesRegex(RuntimeError, "custom exception"):
961961
func(b'key', b'msg', raiser)
962962

963-
with self.assertRaisesRegex(ValueError, 'hash type'):
963+
with self.assertRaisesRegex(ValueError, 'unsupported hash algorithm'):
964964
func(b'key', b'msg', 'unknown')
965965

966966
with self.assertRaisesRegex(AttributeError, 'new'):
Lines changed: 4 additions & 0 deletions

0 commit comments

Comments
 (0)