@@ -99,7 +99,7 @@ int rules_mute, stack_rules_mute;
9999static int fmt_case ;
100100
101101static struct {
102- unsigned int vars [0x100 ];
102+ int vars [0x100 ]; /* may be negative */
103103/*
104104 * pass == -2 initial syntax checking of rules
105105 * pass == -1 optimization of rules (no-ops are removed)
@@ -185,8 +185,10 @@ static char *conv_source = CONV_SOURCE;
185185static char * conv_shift , * conv_invert , * conv_vowels , * conv_right , * conv_left ;
186186static char * conv_tolower , * conv_toupper ;
187187
188- #define INVALID_LENGTH 0x81
189- #define INFINITE_LENGTH 0xFF
188+ /* INFINITE_LENGTH must fit RULE_WORD_SIZE * 2 */
189+ #define INFINITE_LENGTH (MAX_PLAINTEXT_LENGTH * 2)
190+ /* INVALID_LENGTH must be beyond INFINITE_LENGTH */
191+ #define INVALID_LENGTH (INFINITE_LENGTH + 1)
190192
191193#define RULE (*rule++)
192194#define LAST (*(rule - 1))
@@ -200,9 +202,14 @@ static char *conv_tolower, *conv_toupper;
200202 if (!((value) = RULE)) goto out_ERROR_END; \
201203}
202204
205+ /* The pos variable may be signed or unsigned int, which affects comparison */
203206#define POSITION (pos ) { \
204- if (((pos) = rules_vars[ARCH_INDEX(RULE)]) == INVALID_LENGTH) \
205- goto out_ERROR_POSITION; \
207+ if (((pos) = rules_vars[ARCH_INDEX(RULE)]) > INFINITE_LENGTH) { \
208+ if (pos > (unsigned int)-MAX_PLAINTEXT_LENGTH) \
209+ pos = INFINITE_LENGTH; \
210+ else \
211+ goto out_ERROR_POSITION; \
212+ } \
206213}
207214
208215#define CLASS_export_pos (start , true , false ) { \
@@ -520,7 +527,7 @@ static void rules_init_length(int max_length)
520527{
521528 int c ;
522529
523- memset ( rules_vars , INVALID_LENGTH , sizeof ( rules_vars )) ;
530+ for ( c = 0 ; c < 0x100 ; c ++ ) rules_vars [ c ] = INVALID_LENGTH ;
524531
525532 for (c = '0' ; c <= '9' ; c ++ ) rules_vars [c ] = c - '0' ;
526533 for (c = 'A' ; c <= 'Z' ; c ++ ) rules_vars [c ] = c - ('A' - 10 );
@@ -799,7 +806,7 @@ char *rules_apply(char *word_in, char *rule, int split)
799806 * exceed INVALID_LENGTH.
800807 */
801808 rules_vars ['l' ] = length ;
802- rules_vars ['m' ] = ( unsigned char ) length - 1 ;
809+ rules_vars ['m' ] = length - 1 ; /* may be -1 if hc_logic or rules_pass */
803810
804811 if (rules_stacked_after != length_initiated_as ) {
805812 if (rules_stacked_after ) {
@@ -841,15 +848,15 @@ char *rules_apply(char *word_in, char *rule, int split)
841848
842849 case '<' :
843850 {
844- int pos ;
851+ unsigned int pos ;
845852 POSITION (pos )
846853 if (length >= pos ) REJECT
847854 }
848855 break ;
849856
850857 case '>' :
851858 {
852- int pos ;
859+ unsigned int pos ;
853860 POSITION (pos )
854861 if (length <= pos ) REJECT
855862 }
@@ -905,7 +912,7 @@ char *rules_apply(char *word_in, char *rule, int split)
905912 case 'p' :
906913 if (hc_logic || (* rule >= '1' && * rule <= '9' )) {
907914 /* HC rule: duplicate word N times */
908- unsigned char x , y ;
915+ unsigned int x , y ;
909916 POSITION (x )
910917 if (x * length > RULE_WORD_SIZE - 1 )
911918 x = (RULE_WORD_SIZE - 1 ) / length ;
@@ -992,7 +999,7 @@ char *rules_apply(char *word_in, char *rule, int split)
992999 case 'x' :
9931000 if (hc_logic ) {
9941001 /* Slightly different edge logic for HC */
995- int pos , pos2 ;
1002+ unsigned int pos , pos2 ;
9961003 POSITION (pos )
9971004 POSITION (pos2 )
9981005 if (pos < length && pos + pos2 <= length ) {
@@ -1006,7 +1013,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10061013 break ;
10071014 } else
10081015 {
1009- int pos ;
1016+ unsigned int pos ;
10101017 POSITION (pos )
10111018 if (pos < length ) {
10121019 char * out ;
@@ -1024,7 +1031,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10241031
10251032 case 'i' :
10261033 {
1027- int pos ;
1034+ unsigned int pos ;
10281035 POSITION (pos )
10291036 if (pos < length ) {
10301037 char * p = in + pos ;
@@ -1050,7 +1057,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10501057
10511058 case 'o' :
10521059 {
1053- int pos ;
1060+ unsigned int pos ;
10541061 char value ;
10551062 POSITION (pos )
10561063 VALUE (value );
@@ -1089,7 +1096,7 @@ char *rules_apply(char *word_in, char *rule, int split)
10891096
10901097 case '=' :
10911098 {
1092- int pos ;
1099+ unsigned int pos ;
10931100 POSITION (pos )
10941101 if (pos >= length ) {
10951102 SKIP_CLASS
@@ -1162,7 +1169,7 @@ char *rules_apply(char *word_in, char *rule, int split)
11621169
11631170 case '\'' :
11641171 {
1165- int pos ;
1172+ unsigned int pos ;
11661173 POSITION (pos )
11671174 if (pos < length )
11681175 in [length = pos ] = 0 ;
@@ -1171,7 +1178,7 @@ char *rules_apply(char *word_in, char *rule, int split)
11711178
11721179 case '%' :
11731180 {
1174- int count = 0 , required , pos ;
1181+ unsigned int count = 0 , required , pos ;
11751182 POSITION (required )
11761183 CLASS_export_pos (0 ,
11771184 if (++ count >= required ) break , {})
@@ -1183,7 +1190,7 @@ char *rules_apply(char *word_in, char *rule, int split)
11831190/* Rules added in John */
11841191 case 'A' : /* append/insert/prepend string */
11851192 {
1186- int pos ;
1193+ unsigned int pos ;
11871194 char term ;
11881195 POSITION (pos )
11891196 VALUE (term )
@@ -1231,15 +1238,15 @@ char *rules_apply(char *word_in, char *rule, int split)
12311238
12321239 case 'T' :
12331240 {
1234- int pos ;
1241+ unsigned int pos ;
12351242 POSITION (pos )
12361243 in [pos ] = conv_invert [ARCH_INDEX (in [pos ])];
12371244 }
12381245 break ;
12391246
12401247 case 'D' :
12411248 {
1242- int pos ;
1249+ unsigned int pos ;
12431250 POSITION (pos )
12441251 if (pos < length ) {
12451252 memmove (& in [pos ], & in [pos + 1 ],
@@ -1305,7 +1312,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13051312 case 'R' :
13061313 if (hc_logic || (* rule >= '0' && * rule <= '9' )) {
13071314 /* HC rule: bit-shift character right */
1308- unsigned char n ;
1315+ unsigned int n ;
13091316 unsigned char val ;
13101317 POSITION (n )
13111318 if (n < length ) {
@@ -1321,7 +1328,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13211328 case 'L' :
13221329 if (hc_logic || (* rule >= '0' && * rule <= '9' )) {
13231330 /* HC rule: bit-shift character left */
1324- unsigned char n ;
1331+ unsigned int n ;
13251332 unsigned char val ;
13261333 POSITION (n )
13271334 if (n < length ) {
@@ -1375,7 +1382,7 @@ char *rules_apply(char *word_in, char *rule, int split)
13751382
13761383 case 'M' :
13771384 memcpy (memory = memory_buffer , in , length + 1 );
1378- rules_vars ['m' ] = ( unsigned char ) length - 1 ;
1385+ rules_vars ['m' ] = length - 1 ;
13791386 break ;
13801387
13811388 case 'Q' :
@@ -1388,14 +1395,15 @@ char *rules_apply(char *word_in, char *rule, int split)
13881395
13891396 case 'X' : /* append/insert/prepend substring from memory */
13901397 {
1391- int mpos , count , ipos , mleft ;
1398+ unsigned int mpos , ucount , ipos ;
1399+ int count , mleft ;
13921400 char * inp ;
13931401 const char * mp ;
13941402 POSITION (mpos )
1395- POSITION (count )
1403+ POSITION (ucount )
13961404 POSITION (ipos )
1397- mleft = ( int )( unsigned char )
1398- ( rules_vars ['m' ] + 1 ) - mpos ;
1405+ count = ucount ;
1406+ mleft = rules_vars ['m' ] + 1 - ( int ) mpos ; /* may be negative */
13991407 if (count > mleft )
14001408 count = mleft ;
14011409 if (count <= 0 )
@@ -1416,14 +1424,14 @@ char *rules_apply(char *word_in, char *rule, int split)
14161424 case 'v' : /* assign value to numeric variable */
14171425 {
14181426 char var ;
1419- unsigned char a , s ;
1427+ int a , s ; /* may be negative */
14201428 VALUE (var )
14211429 if (var < 'a' || var > 'k' )
14221430 goto out_ERROR_POSITION ;
14231431 rules_vars ['l' ] = length ;
14241432 POSITION (a )
14251433 POSITION (s )
1426- rules_vars [ARCH_INDEX (var )] = a - s ;
1434+ rules_vars [ARCH_INDEX (var )] = a - s ; /* may be negative */
14271435 }
14281436 break ;
14291437
@@ -1469,7 +1477,7 @@ char *rules_apply(char *word_in, char *rule, int split)
14691477 case '+' :
14701478 if (hc_logic || !which ) {
14711479 /* HC rule: increment character */
1472- unsigned char x ;
1480+ unsigned int x ;
14731481 POSITION (x )
14741482 if (x < length )
14751483 ++ in [x ];
@@ -1501,7 +1509,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15011509/* Rules added in Jumbo */
15021510 case 'a' :
15031511 {
1504- int pos ;
1512+ unsigned int pos ;
15051513 POSITION (pos )
15061514 if (!rules_stacked_after ) {
15071515 if (length + pos > rules_max_length )
@@ -1514,7 +1522,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15141522
15151523 case 'b' :
15161524 {
1517- int pos ;
1525+ unsigned int pos ;
15181526 POSITION (pos )
15191527 if (!rules_stacked_after ) {
15201528 if (length - pos > rules_max_length )
@@ -1527,7 +1535,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15271535
15281536 case 'W' :
15291537 {
1530- int pos ;
1538+ unsigned int pos ;
15311539 POSITION (pos )
15321540 in [pos ] = conv_shift [ARCH_INDEX (in [pos ])];
15331541 }
@@ -1541,15 +1549,15 @@ char *rules_apply(char *word_in, char *rule, int split)
15411549/* Hashcat rules added to Jumbo */
15421550 case '_' : /* reject unless length equals to N */
15431551 {
1544- int pos ;
1552+ unsigned int pos ;
15451553 POSITION (pos )
15461554 if (length != pos ) REJECT
15471555 }
15481556 break ;
15491557
15501558 case '-' : /* decrement character */
15511559 {
1552- unsigned char x ;
1560+ unsigned int x ;
15531561 POSITION (x )
15541562 if (x < length )
15551563 -- in [x ];
@@ -1568,7 +1576,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15681576
15691577 case '*' : /* swap any two characters */
15701578 {
1571- unsigned char x , y ;
1579+ unsigned int x , y ;
15721580 POSITION (x )
15731581 POSITION (y )
15741582 if (length > x && length > y )
@@ -1578,8 +1586,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15781586
15791587 case 'z' : /* duplicate first char N times */
15801588 {
1581- unsigned char x ;
1582- int y ;
1589+ unsigned int x , y ;
15831590 POSITION (x )
15841591 y = length ;
15851592 while (y ) {
@@ -1597,7 +1604,7 @@ char *rules_apply(char *word_in, char *rule, int split)
15971604
15981605 case 'Z' : /* duplicate char char N times */
15991606 {
1600- unsigned char x ;
1607+ unsigned int x ;
16011608 POSITION (x )
16021609 while (x ) {
16031610 in [length ] = in [length - 1 ];
@@ -1622,7 +1629,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16221629
16231630 case '.' : /* replace character with next */
16241631 {
1625- unsigned char n ;
1632+ unsigned int n ;
16261633 POSITION (n )
16271634 if (n < length - 1 && length > 1 )
16281635 in [n ] = in [n + 1 ];
@@ -1631,7 +1638,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16311638
16321639 case ',' : /* replace character with prior */
16331640 {
1634- unsigned char n ;
1641+ unsigned int n ;
16351642 POSITION (n )
16361643 if (n >= 1 && length > 1 && n < length )
16371644 in [n ] = in [n - 1 ];
@@ -1640,7 +1647,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16401647
16411648 case 'y' : /* duplicate first n characters */
16421649 {
1643- unsigned char n ;
1650+ unsigned int n ;
16441651 POSITION (n )
16451652 if (n <= length ) {
16461653 memmove (& in [n ], in , length );
@@ -1652,7 +1659,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16521659
16531660 case 'Y' : /* duplicate last n characters */
16541661 {
1655- unsigned char n ;
1662+ unsigned int n ;
16561663 POSITION (n )
16571664 if (n <= length ) {
16581665 memmove (& in [length ], & in [length - n ], n );
@@ -1683,7 +1690,7 @@ char *rules_apply(char *word_in, char *rule, int split)
16831690
16841691 case 'O' : /* Omit */
16851692 {
1686- int pos , pos2 ;
1693+ unsigned int pos , pos2 ;
16871694 POSITION (pos )
16881695 POSITION (pos2 )
16891696 if (pos < length && pos + pos2 <= length ) {
0 commit comments