Buggy code:
public class Sha2Crypt { private static final int ROUNDS_DEFAULT = 5000 ; private static final int ROUNDS_MAX = 999999999 ; private static final int ROUNDS_MIN = 1000 ; private static final String ROUNDS_PREFIX = "rounds=" ; private static final String SHA256_ALGORITHM = "SHA-256" ; private static final int SHA256_BLOCKSIZE = 32 ; static final String SHA256_PREFIX = "$5$" ; private static final String SHA512_ALGORITHM = "SHA-512" ; private static final int SHA512_BLOCKSIZE = 64 ; static final String SHA512_PREFIX = "$6$" ; public static String sha256Crypt ( byte [ ] keyBytes ) throws Exception { } public static String sha256Crypt ( byte [ ] keyBytes , String salt ) throws Exception { } private static String sha2Crypt ( byte [ ] keyBytes , String salt , String saltPrefix , int blocksize , String algorithm ) throws Exception { int keyLen = keyBytes . length ; int rounds = Sha2Crypt . ROUNDS_DEFAULT ; boolean roundsCustom = false ; if ( salt == null ) { throw new IllegalArgumentException ( "Invalid<seq2seq4repair_space>salt<seq2seq4repair_space>value:<seq2seq4repair_space>null" ) ; } Pattern p = Pattern . compile ( "^\\$([56])\\$(rounds=(\\d+)\\$)?([\\.\\//a-zA-Z0-9]{1,16}).*" ) ; Matcher m = p . matcher ( salt ) ; if ( ( m == null ) || ( ! ( m . find ( ) ) ) ) { throw new IllegalArgumentException ( ( "Invalid<seq2seq4repair_space>salt<seq2seq4repair_space>value:<seq2seq4repair_space>" + salt ) ) ; } if ( ( m . group ( 3 ) ) != null ) { <START_BUG> rounds = Integer . valueOf ( m . group ( 3 ) ) ; <END_BUG> rounds = Math . max ( Sha2Crypt . ROUNDS_MIN , Math . min ( Sha2Crypt . ROUNDS_MAX , rounds ) ) ; roundsCustom = true ; } String saltString = m . group ( 4 ) ; byte [ ] saltBytes = saltString . getBytes ( "UTF-8" ) ; int saltLen = saltBytes . length ; MessageDigest ctx = MessageDigest . getInstance ( algorithm ) ; ctx . update ( keyBytes ) ; ctx . update ( saltBytes ) ; MessageDigest altCtx = MessageDigest . getInstance ( algorithm ) ; altCtx . update ( keyBytes ) ; altCtx . update ( saltBytes ) ; altCtx . update ( keyBytes ) ; byte [ ] altResult = altCtx . digest ( ) ; int cnt = keyBytes . length ; while ( cnt > blocksize ) { ctx . update ( altResult , 0 , blocksize ) ; cnt -= blocksize ; } ctx . update ( altResult , 0 , cnt ) ; cnt = keyBytes . length ; while ( cnt > 0 ) { if ( ( cnt & 1 ) != 0 ) { ctx . update ( altResult , 0 , blocksize ) ; } else { ctx . update ( keyBytes ) ; } cnt >>= 1 ; } altResult = ctx . digest ( ) ; altCtx = MessageDigest . getInstance ( algorithm ) ; for ( int i = 1 ; i <= keyLen ; i ++ ) { altCtx . update ( keyBytes ) ; } byte [ ] tempResult = altCtx . digest ( ) ; byte [ ] pBytes = new byte [ keyLen ] ; int cp = 0 ; while ( cp < ( keyLen - blocksize ) ) { System . arraycopy ( tempResult , 0 , pBytes , cp , blocksize ) ; cp += blocksize ; } System . arraycopy ( tempResult , 0 , pBytes , cp , ( keyLen - cp ) ) ; altCtx = MessageDigest . getInstance ( algorithm ) ; for ( int i = 1 ; i <= ( 16 + ( ( altResult [ 0 ] ) & 255 ) ) ; i ++ ) { altCtx . update ( saltBytes ) ; } tempResult = altCtx . digest ( ) ; byte [ ] sBytes = new byte [ saltLen ] ; cp = 0 ; while ( cp < ( saltLen - blocksize ) ) { System . arraycopy ( tempResult , 0 , sBytes , cp , blocksize ) ; cp += blocksize ; } System . arraycopy ( tempResult , 0 , sBytes , cp , ( saltLen - cp ) ) ; for ( int i = 0 ; i <= ( rounds - 1 ) ; i ++ ) { ctx = MessageDigest . getInstance ( algorithm ) ; if ( ( i & 1 ) != 0 ) { ctx . update ( pBytes , 0 , keyLen ) ; } else { ctx . update ( altResult , 0 , blocksize ) ; } if ( ( i % 3 ) != 0 ) { ctx . update ( sBytes , 0 , saltLen ) ; } if ( ( i % 7 ) != 0 ) { ctx . update ( pBytes , 0 , keyLen ) ; } if ( ( i & 1 ) != 0 ) { ctx . update ( altResult , 0 , blocksize ) ; } else { ctx . update ( pBytes , 0 , keyLen ) ; } altResult = ctx . digest ( ) ; } StringBuilder buffer = new StringBuilder ( ( ( ( saltPrefix + ( roundsCustom ? ( ( Sha2Crypt . ROUNDS_PREFIX ) + rounds ) + "$" : "" ) ) + saltString ) + "$" ) ) ; if ( blocksize == 32 ) { B64 . b64from24bit ( altResult [ 0 ] , altResult [ 10 ] , altResult [ 20 ] , 4 , buffer ) ; B64 . b64from24bit ( altResult [ 21 ] , altResult [ 1 ] , altResult [ 11 ] , 4 , buffer ) ; B64 . b64from24bit ( altResult [ 12 ] , altResult [ 22 ] , altResult [ 2 ] , 4 , buffer ) ; B64 . b64from24bit ( altResult [ 3 ] , altResult [ 13 ] , altResult [ 23 ] , 4 , buffer ) ;

Fix:
rounds = Integer . parseInt ( m . group ( 3 ) ) ;