Skip to content

Commit d035cd6

Browse files
committed
Rules: Complete support for lengths beyond 128
See #5873
1 parent 6612f2a commit d035cd6

File tree

1 file changed

+51
-44
lines changed

1 file changed

+51
-44
lines changed

src/rules.c

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ int rules_mute, stack_rules_mute;
9999
static int fmt_case;
100100

101101
static 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;
185185
static char *conv_shift, *conv_invert, *conv_vowels, *conv_right, *conv_left;
186186
static 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

Comments
 (0)