37 |
|
|
38 |
#define LOOPREPEAT 50000 |
#define LOOPREPEAT 50000 |
39 |
|
|
40 |
|
#define BUFFER_SIZE 30000 |
41 |
|
#define DBUFFER_SIZE 1024 |
42 |
|
|
43 |
|
|
44 |
static FILE *outfile; |
static FILE *outfile; |
45 |
static int log_store = 0; |
static int log_store = 0; |
48 |
static int callout_fail_count; |
static int callout_fail_count; |
49 |
static int callout_fail_id; |
static int callout_fail_id; |
50 |
static int first_callout; |
static int first_callout; |
51 |
static int utf8; |
static int use_utf8; |
52 |
static size_t gotten_store; |
static size_t gotten_store; |
53 |
|
|
54 |
|
|
55 |
|
|
56 |
static int utf8_table1[] = { |
static const int utf8_table1[] = { |
57 |
0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; |
0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; |
58 |
|
|
59 |
static int utf8_table2[] = { |
static const int utf8_table2[] = { |
60 |
0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; |
0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; |
61 |
|
|
62 |
static int utf8_table3[] = { |
static const int utf8_table3[] = { |
63 |
0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; |
0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; |
64 |
|
|
65 |
|
|
158 |
-6 to 0 => malformed UTF-8 character at offset = (-return) |
-6 to 0 => malformed UTF-8 character at offset = (-return) |
159 |
*/ |
*/ |
160 |
|
|
161 |
int |
static int |
162 |
utf82ord(unsigned char *buffer, int *vptr) |
utf82ord(unsigned char *buffer, int *vptr) |
163 |
{ |
{ |
164 |
int c = *buffer++; |
int c = *buffer++; |
216 |
|
|
217 |
while (length-- > 0) |
while (length-- > 0) |
218 |
{ |
{ |
219 |
if (utf8) |
if (use_utf8) |
220 |
{ |
{ |
221 |
int rc = utf82ord(p, &c); |
int rc = utf82ord(p, &c); |
222 |
|
|
273 |
|
|
274 |
if (callout_extra) |
if (callout_extra) |
275 |
{ |
{ |
|
int i; |
|
276 |
fprintf(f, "Callout %d: last capture = %d\n", |
fprintf(f, "Callout %d: last capture = %d\n", |
277 |
cb->callout_number, cb->capture_last); |
cb->callout_number, cb->capture_last); |
278 |
|
|
390 |
#endif |
#endif |
391 |
int debug = 0; |
int debug = 0; |
392 |
int done = 0; |
int done = 0; |
393 |
unsigned char buffer[30000]; |
|
394 |
unsigned char dbuffer[1024]; |
unsigned char *buffer; |
395 |
|
unsigned char *dbuffer; |
396 |
|
|
397 |
|
/* Get buffers from malloc() so that Electric Fence will check their misuse |
398 |
|
when I am debugging. */ |
399 |
|
|
400 |
|
buffer = malloc(BUFFER_SIZE); |
401 |
|
dbuffer = malloc(DBUFFER_SIZE); |
402 |
|
|
403 |
/* Static so that new_malloc can use it. */ |
/* Static so that new_malloc can use it. */ |
404 |
|
|
525 |
int do_showrest = 0; |
int do_showrest = 0; |
526 |
int erroroffset, len, delimiter; |
int erroroffset, len, delimiter; |
527 |
|
|
528 |
utf8 = 0; |
use_utf8 = 0; |
529 |
|
|
530 |
if (infile == stdin) printf(" re> "); |
if (infile == stdin) printf(" re> "); |
531 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break; |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break; |
532 |
if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); |
if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); |
533 |
fflush(outfile); |
fflush(outfile); |
534 |
|
|
559 |
} |
} |
560 |
if (*pp != 0) break; |
if (*pp != 0) break; |
561 |
|
|
562 |
len = sizeof(buffer) - (pp - buffer); |
len = BUFFER_SIZE - (pp - buffer); |
563 |
if (len < 256) |
if (len < 256) |
564 |
{ |
{ |
565 |
fprintf(outfile, "** Expression too long - missing delimiter?\n"); |
fprintf(outfile, "** Expression too long - missing delimiter?\n"); |
618 |
case 'S': do_study = 1; break; |
case 'S': do_study = 1; break; |
619 |
case 'U': options |= PCRE_UNGREEDY; break; |
case 'U': options |= PCRE_UNGREEDY; break; |
620 |
case 'X': options |= PCRE_EXTRA; break; |
case 'X': options |= PCRE_EXTRA; break; |
621 |
case '8': options |= PCRE_UTF8; utf8 = 1; break; |
case '8': options |= PCRE_UTF8; use_utf8 = 1; break; |
622 |
|
|
623 |
case 'L': |
case 'L': |
624 |
ppp = pp; |
ppp = pp; |
658 |
|
|
659 |
if (rc != 0) |
if (rc != 0) |
660 |
{ |
{ |
661 |
(void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); |
(void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); |
662 |
fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); |
fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); |
663 |
goto SKIP_DATA; |
goto SKIP_DATA; |
664 |
} |
} |
699 |
{ |
{ |
700 |
for (;;) |
for (;;) |
701 |
{ |
{ |
702 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) |
703 |
{ |
{ |
704 |
done = 1; |
done = 1; |
705 |
goto CONTINUE; |
goto CONTINUE; |
746 |
new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); |
new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); |
747 |
new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); |
new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); |
748 |
new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); |
new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); |
749 |
new_info(re, NULL, PCRE_INFO_NAMETABLE, &nametable); |
new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); |
750 |
|
|
751 |
old_count = pcre_info(re, &old_options, &old_first_char); |
old_count = pcre_info(re, &old_options, &old_first_char); |
752 |
if (count < 0) fprintf(outfile, |
if (count < 0) fprintf(outfile, |
812 |
else |
else |
813 |
{ |
{ |
814 |
int ch = first_char & 255; |
int ch = first_char & 255; |
815 |
char *caseless = ((first_char & REQ_CASELESS) == 0)? |
const char *caseless = ((first_char & REQ_CASELESS) == 0)? |
816 |
"" : " (caseless)"; |
"" : " (caseless)"; |
817 |
if (isprint(ch)) |
if (isprint(ch)) |
818 |
fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); |
fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); |
827 |
else |
else |
828 |
{ |
{ |
829 |
int ch = need_char & 255; |
int ch = need_char & 255; |
830 |
char *caseless = ((need_char & REQ_CASELESS) == 0)? |
const char *caseless = ((need_char & REQ_CASELESS) == 0)? |
831 |
"" : " (caseless)"; |
"" : " (caseless)"; |
832 |
if (isprint(ch)) |
if (isprint(ch)) |
833 |
fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); |
fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); |
931 |
callout_fail_id = -1; |
callout_fail_id = -1; |
932 |
|
|
933 |
if (infile == stdin) printf("data> "); |
if (infile == stdin) printf("data> "); |
934 |
if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) |
if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) |
935 |
{ |
{ |
936 |
done = 1; |
done = 1; |
937 |
goto CONTINUE; |
goto CONTINUE; |
982 |
c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); |
c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); |
983 |
if (*pt == '}') |
if (*pt == '}') |
984 |
{ |
{ |
985 |
unsigned char buffer[8]; |
unsigned char buff8[8]; |
986 |
int ii, utn; |
int ii, utn; |
987 |
utn = ord2utf8(c, buffer); |
utn = ord2utf8(c, buff8); |
988 |
for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii]; |
for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; |
989 |
c = buffer[ii]; /* Last byte */ |
c = buff8[ii]; /* Last byte */ |
990 |
p = pt + 1; |
p = pt + 1; |
991 |
break; |
break; |
992 |
} |
} |
1024 |
else if (isalnum(*p)) |
else if (isalnum(*p)) |
1025 |
{ |
{ |
1026 |
uschar name[256]; |
uschar name[256]; |
1027 |
uschar *pp = name; |
uschar *npp = name; |
1028 |
while (isalnum(*p)) *pp++ = *p++; |
while (isalnum(*p)) *npp++ = *p++; |
1029 |
*pp = 0; |
*npp = 0; |
1030 |
n = pcre_get_stringnumber(re, (char *)name); |
n = pcre_get_stringnumber(re, (char *)name); |
1031 |
if (n < 0) |
if (n < 0) |
1032 |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
1077 |
else if (isalnum(*p)) |
else if (isalnum(*p)) |
1078 |
{ |
{ |
1079 |
uschar name[256]; |
uschar name[256]; |
1080 |
uschar *pp = name; |
uschar *npp = name; |
1081 |
while (isalnum(*p)) *pp++ = *p++; |
while (isalnum(*p)) *npp++ = *p++; |
1082 |
*pp = 0; |
*npp = 0; |
1083 |
n = pcre_get_stringnumber(re, (char *)name); |
n = pcre_get_stringnumber(re, (char *)name); |
1084 |
if (n < 0) |
if (n < 0) |
1085 |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
fprintf(outfile, "no parentheses with name \"%s\"\n", name); |
1144 |
|
|
1145 |
if (rc != 0) |
if (rc != 0) |
1146 |
{ |
{ |
1147 |
(void)regerror(rc, &preg, (char *)buffer, sizeof(buffer)); |
(void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); |
1148 |
fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); |
fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); |
1149 |
} |
} |
1150 |
else |
else |