2121import hmac
2222import hashlib
2323import random
24- import test .support
25- import test .support .hashlib_helper as hashlib_helper
2624import types
2725import unittest
28- import unittest .mock as mock
2926import warnings
3027from _operator import _compare_digest as operator_compare_digest
28+ from test .support import _4G , bigmemtest
3129from test .support import check_disallow_instantiation
30+ from test .support import hashlib_helper , import_helper
3231from test .support .hashlib_helper import (
3332 BuiltinHashFunctionsTrait ,
3433 HashFunctionsTrait ,
3534 NamedHashFunctionsTrait ,
3635 OpenSSLHashFunctionsTrait ,
3736)
38- from test .support .import_helper import import_fresh_module , import_module
37+ from test .support .import_helper import import_fresh_module
38+ from unittest .mock import patch
3939
4040try :
4141 import _hashlib
@@ -728,7 +728,7 @@ def setUpClass(cls):
728728 super ().setUpClass ()
729729 for meth in ['_init_openssl_hmac' , '_init_builtin_hmac' ]:
730730 fn = getattr (cls .hmac .HMAC , meth )
731- cm = mock . patch .object (cls .hmac .HMAC , meth , autospec = True , wraps = fn )
731+ cm = patch .object (cls .hmac .HMAC , meth , autospec = True , wraps = fn )
732732 cls .enterClassContext (cm )
733733
734734 @classmethod
@@ -950,7 +950,11 @@ class PyConstructorTestCase(ThroughObjectMixin, PyConstructorBaseMixin,
950950
951951class PyModuleConstructorTestCase (ThroughModuleAPIMixin , PyConstructorBaseMixin ,
952952 unittest .TestCase ):
953- """Test the hmac.new() and hmac.digest() functions."""
953+ """Test the hmac.new() and hmac.digest() functions.
954+
955+ Note that "self.hmac" is imported by blocking "_hashlib" and "_hmac".
956+ For testing functions in "hmac", extend PyMiscellaneousTests instead.
957+ """
954958
955959 def test_hmac_digest_digestmod_parameter (self ):
956960 func = self .hmac_digest
@@ -1446,9 +1450,8 @@ def test_hmac_constructor_uses_builtin(self):
14461450 hmac = import_fresh_module ("hmac" , blocked = ["_hashlib" ])
14471451
14481452 def watch_method (cls , name ):
1449- return mock .patch .object (
1450- cls , name , autospec = True , wraps = getattr (cls , name )
1451- )
1453+ wraps = getattr (cls , name )
1454+ return patch .object (cls , name , autospec = True , wraps = wraps )
14521455
14531456 with (
14541457 watch_method (hmac .HMAC , '_init_openssl_hmac' ) as f ,
@@ -1500,6 +1503,48 @@ def test_with_fallback(self):
15001503 finally :
15011504 cache .pop ('foo' )
15021505
1506+ @hashlib_helper .requires_openssl_hashdigest ("md5" )
1507+ @bigmemtest (size = _4G + 5 , memuse = 2 , dry_run = False )
1508+ def test_hmac_digest_overflow_error_openssl_only (self , size ):
1509+ hmac = import_fresh_module ("hmac" , blocked = ["_hmac" ])
1510+ self .do_test_hmac_digest_overflow_error_switch_to_slow (hmac , size )
1511+
1512+ @hashlib_helper .requires_builtin_hashdigest ("_md5" , "md5" )
1513+ @bigmemtest (size = _4G + 5 , memuse = 2 , dry_run = False )
1514+ def test_hmac_digest_overflow_error_builtin_only (self , size ):
1515+ hmac = import_fresh_module ("hmac" , blocked = ["_hashlib" ])
1516+ self .do_test_hmac_digest_overflow_error_switch_to_slow (hmac , size )
1517+
1518+ def do_test_hmac_digest_overflow_error_switch_to_slow (self , hmac , size ):
1519+ """Check that hmac.digest() falls back to pure Python.
1520+
1521+ The *hmac* argument implements the HMAC module interface.
1522+ The *size* argument is a large key size or message size that would
1523+ trigger an OverflowError in the C implementation(s) of hmac.digest().
1524+ """
1525+
1526+ bigkey = b'K' * size
1527+ bigmsg = b'M' * size
1528+
1529+ with patch .object (hmac , "_compute_digest_fallback" ) as slow :
1530+ hmac .digest (bigkey , b'm' , "md5" )
1531+ slow .assert_called_once ()
1532+
1533+ with patch .object (hmac , "_compute_digest_fallback" ) as slow :
1534+ hmac .digest (b'k' , bigmsg , "md5" )
1535+ slow .assert_called_once ()
1536+
1537+ @hashlib_helper .requires_hashdigest ("md5" , openssl = True )
1538+ @bigmemtest (size = _4G + 5 , memuse = 2 , dry_run = False )
1539+ def test_hmac_digest_no_overflow_error_in_fallback (self , size ):
1540+ hmac = import_fresh_module ("hmac" , blocked = ["_hashlib" , "_hmac" ])
1541+
1542+ for key , msg in [(b'K' * size , b'm' ), (b'k' , b'M' * size )]:
1543+ with self .subTest (keysize = len (key ), msgsize = len (msg )):
1544+ with patch .object (hmac , "_compute_digest_fallback" ) as slow :
1545+ hmac .digest (key , msg , "md5" )
1546+ slow .assert_called_once ()
1547+
15031548
15041549class BuiltinMiscellaneousTests (BuiltinModuleMixin , unittest .TestCase ):
15051550 """HMAC-BLAKE2 is not standardized as BLAKE2 is a keyed hash function.
@@ -1512,7 +1557,7 @@ class BuiltinMiscellaneousTests(BuiltinModuleMixin, unittest.TestCase):
15121557 @classmethod
15131558 def setUpClass (cls ):
15141559 super ().setUpClass ()
1515- cls .blake2 = import_module ("_blake2" )
1560+ cls .blake2 = import_helper . import_module ("_blake2" )
15161561 cls .blake2b = cls .blake2 .blake2b
15171562 cls .blake2s = cls .blake2 .blake2s
15181563
0 commit comments