@@ -462,7 +462,11 @@ def test_empty_passwords(self):
462462 self .assertEqual (ctx .exception .args [0 ],
463463 'Password not set' )
464464
465- p = roundup .password .Password ()
465+ with self .assertRaises (ValueError ) as ctx :
466+ p .__str__ ()
467+
468+ self .assertEqual (ctx .exception .args [0 ],
469+ 'Password not set' )
466470
467471 # make sure it uses the default scheme
468472 default_scheme = roundup .password .Password .default_scheme
@@ -483,6 +487,11 @@ def test_pbkdf2_migrate_rounds(self):
483487 self .assertEqual (p .needs_migration (config = self .db .config ), True )
484488 del (os .environ ["PYTEST_USE_CONFIG" ])
485489
490+ # set up p with rounds under 1000. This is usually prevented,
491+ # but older software could generate smaller rounds.
492+ p .password = p .password .replace ('1000$' , '900$' )
493+ self .assertEqual (p .needs_migration (config = self .db .config ), True )
494+
486495 def test_encodePassword_errors (self ):
487496 self .db .config .PASSWORD_PBKDF2_DEFAULT_ROUNDS = 999
488497
@@ -531,6 +540,47 @@ def test_pbkdf2_sha512_errors(self):
531540 self .assertEqual (ctx .exception .args [0 ],
532541 "rounds must be positive number" )
533542
543+ def test_misc_functions (self ):
544+ import random # for fuzzing later
545+
546+ v = roundup .password .bchr (64 )
547+ if bytes == str :
548+ self .assertEqual (v , '@' )
549+ else :
550+ self .assertEqual (v , b'@' )
551+
552+ v = roundup .password .bord (b'@' )
553+ if bytes == str :
554+ self .assertEqual (v , 64 )
555+ else :
556+ self .assertEqual (v , b'@' )
557+
558+ for plain , encode in (
559+ (b'tes' , 'dGVz' ),
560+ (b'test' , 'dGVzdA' ),
561+ (b'testb' , "dGVzdGI" ),
562+ ):
563+ v = roundup .password .h64encode (plain )
564+ self .assertEqual (v , encode )
565+ v = roundup .password .h64decode (v )
566+ self .assertEqual (v , plain )
567+
568+ with self .assertRaises (ValueError ) as ctx :
569+ v = roundup .password .h64decode ("dGVzd" )
570+ self .assertEqual (ctx .exception .args [0 ], "Invalid base64 input" )
571+
572+ # poor man's fuzzer
573+ if bytes == str :
574+ # alias range to xrange for python2, more efficient.
575+ range_ = xrange # noqa: F821
576+ else :
577+ range_ = range
578+
579+ for i in range_ (25 ):
580+ plain = bytearray (random .getrandbits (8 ) for _ in range_ (i * 4 ))
581+ e = roundup .password .h64encode (plain )
582+ self .assertEqual (roundup .password .h64decode (e ), plain )
583+
534584 def test_encodePasswordNoConfig (self ):
535585 # should run cleanly as we are in a test.
536586 #
0 commit comments