| 40 |
----------------------------------------------------------------------------- |
----------------------------------------------------------------------------- |
| 41 |
*/ |
*/ |
| 42 |
|
|
| 43 |
|
#ifdef HAVE_CONFIG_H |
| 44 |
|
#include "config.h" |
| 45 |
|
#endif |
| 46 |
|
|
| 47 |
#include <stdio.h> |
#include <stdio.h> |
| 48 |
#include <string.h> |
#include <string.h> |
|
#include <time.h> |
|
| 49 |
#include "pcre.h" |
#include "pcre.h" |
| 50 |
|
|
| 51 |
#define PCRE_BUG 0x80000000 |
#define PCRE_BUG 0x80000000 |
| 60 |
\xe2\x80\xa8 = 0x2028 (Line Separator) |
\xe2\x80\xa8 = 0x2028 (Line Separator) |
| 61 |
\xc8\xba = 570 \xe2\xb1\xa5 = 11365 (lowercase length != uppercase length) |
\xc8\xba = 570 \xe2\xb1\xa5 = 11365 (lowercase length != uppercase length) |
| 62 |
\xcc\x8d = 781 (Something with Mark property) |
\xcc\x8d = 781 (Something with Mark property) |
| 63 |
*/ |
*/ |
| 64 |
|
|
| 65 |
static void setstack(pcre_extra *extra); |
static void setstack(pcre_extra *extra); |
| 66 |
static void regression_tests(void); |
static int regression_tests(void); |
| 67 |
|
|
| 68 |
int main(void) |
int main(void) |
| 69 |
{ |
{ |
| 70 |
regression_tests(); |
int jit = 0; |
| 71 |
return 0; |
pcre_config(PCRE_CONFIG_JIT, &jit); |
| 72 |
|
if (!jit) { |
| 73 |
|
printf("JIT must be enabled to run pcre_jit_test\n"); |
| 74 |
|
return 1; |
| 75 |
|
} |
| 76 |
|
return regression_tests(); |
| 77 |
} |
} |
| 78 |
|
|
| 79 |
static pcre_jit_stack* callback(void *arg) |
static pcre_jit_stack* callback(void *arg) |
| 129 |
{ MUA, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, |
{ MUA, 0, "[^a-dA-C]", "\xe6\x92\xad\xc3\xa9" }, |
| 130 |
{ CMUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, |
{ CMUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, |
| 131 |
{ MUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, |
{ MUA, 0, "[^\xc3\xa9]", "\xc3\xa9\xc3\x89." }, |
| 132 |
{ MUA, 0, "[^a]", "\xc2\x80[]" }, |
{ MUA, 0, "[^a]", "\xc2\x80[]" }, |
| 133 |
{ CMUA, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, |
{ CMUA, 0, "\xf0\x90\x90\xa7", "\xf0\x90\x91\x8f" }, |
| 134 |
{ CMA, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, |
{ CMA, 0, "1a2b3c4", "1a2B3c51A2B3C4" }, |
| 135 |
{ PCRE_CASELESS, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, |
{ PCRE_CASELESS, 0, "\xff#a", "\xff#\xff\xfe##\xff#A" }, |
| 136 |
{ PCRE_CASELESS, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, |
{ PCRE_CASELESS, 0, "\xfe", "\xff\xfc#\xfe\xfe" }, |
| 137 |
{ PCRE_CASELESS, 0, "a1", "Aa1" }, |
{ PCRE_CASELESS, 0, "a1", "Aa1" }, |
| 138 |
|
{ MA, 0, "\\Ca", "cda" }, |
| 139 |
|
{ CMA, 0, "\\Ca", "CDA" }, |
| 140 |
|
{ MA, 0, "\\Cx", "cda" }, |
| 141 |
|
{ CMA, 0, "\\Cx", "CDA" }, |
| 142 |
|
|
| 143 |
/* Assertions. */ |
/* Assertions. */ |
| 144 |
{ MUA, 0, "\\b[^A]", "A_B#" }, |
{ MUA, 0, "\\b[^A]", "A_B#" }, |
| 389 |
{ MUA, 0, "(c(ab)?+ab)+", "cabcababcab" }, |
{ MUA, 0, "(c(ab)?+ab)+", "cabcababcab" }, |
| 390 |
{ MUA, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, |
{ MUA, 0, "(?>(a+)b)+aabab", "aaaabaaabaabab" }, |
| 391 |
|
|
| 392 |
/* Possessive quantifiers. */ |
/* Possessive quantifiers. */ |
| 393 |
{ MUA, 0, "(?:a|b)++m", "mababbaaxababbaam" }, |
{ MUA, 0, "(?:a|b)++m", "mababbaaxababbaam" }, |
| 394 |
{ MUA, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, |
{ MUA, 0, "(?:a|b)*+m", "mababbaaxababbaam" }, |
| 395 |
{ MUA, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, |
{ MUA, 0, "(?:a|b)*+m", "ababbaaxababbaam" }, |
| 396 |
{ MUA, 0, "(a|b)++m", "mababbaaxababbaam" }, |
{ MUA, 0, "(a|b)++m", "mababbaaxababbaam" }, |
| 397 |
{ MUA, 0, "(a|b)*+m", "mababbaaxababbaam" }, |
{ MUA, 0, "(a|b)*+m", "mababbaaxababbaam" }, |
| 398 |
{ MUA, 0, "(a|b)*+m", "ababbaaxababbaam" }, |
{ MUA, 0, "(a|b)*+m", "ababbaaxababbaam" }, |
| 399 |
{ MUA, 0, "(a|b(*ACCEPT))++m", "maaxab" }, |
{ MUA, 0, "(a|b(*ACCEPT))++m", "maaxab" }, |
| 400 |
{ MUA, 0, "(?:b*)++m", "bxbbxbbbxm" }, |
{ MUA, 0, "(?:b*)++m", "bxbbxbbbxm" }, |
| 401 |
{ MUA, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, |
{ MUA, 0, "(?:b*)++m", "bxbbxbbbxbbm" }, |
| 405 |
{ MUA, 0, "(b*)++m", "bxbbxbbbxbbm" }, |
{ MUA, 0, "(b*)++m", "bxbbxbbbxbbm" }, |
| 406 |
{ MUA, 0, "(b*)*+m", "bxbbxbbbxm" }, |
{ MUA, 0, "(b*)*+m", "bxbbxbbbxm" }, |
| 407 |
{ MUA, 0, "(b*)*+m", "bxbbxbbbxbbm" }, |
{ MUA, 0, "(b*)*+m", "bxbbxbbbxbbm" }, |
| 408 |
{ MUA, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, |
{ MUA, 0, "(?:a|(b))++m", "mababbaaxababbaam" }, |
| 409 |
{ MUA, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, |
{ MUA, 0, "(?:(a)|b)*+m", "mababbaaxababbaam" }, |
| 410 |
{ MUA, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, |
{ MUA, 0, "(?:(a)|(b))*+m", "ababbaaxababbaam" }, |
| 411 |
{ MUA, 0, "(a|(b))++m", "mababbaaxababbaam" }, |
{ MUA, 0, "(a|(b))++m", "mababbaaxababbaam" }, |
| 412 |
{ MUA, 0, "((a)|b)*+m", "mababbaaxababbaam" }, |
{ MUA, 0, "((a)|b)*+m", "mababbaaxababbaam" }, |
| 413 |
{ MUA, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, |
{ MUA, 0, "((a)|(b))*+m", "ababbaaxababbaam" }, |
| 414 |
{ MUA, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, |
{ MUA, 0, "(a|(b)(*ACCEPT))++m", "maaxab" }, |
| 415 |
{ MUA, 0, "(?:(b*))++m", "bxbbxbbbxm" }, |
{ MUA, 0, "(?:(b*))++m", "bxbbxbbbxm" }, |
| 416 |
{ MUA, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, |
{ MUA, 0, "(?:(b*))++m", "bxbbxbbbxbbm" }, |
| 530 |
{ MUA, 0, "(?(?!b)a*)+aak", "aaaaab aaaaak" }, |
{ MUA, 0, "(?(?!b)a*)+aak", "aaaaab aaaaak" }, |
| 531 |
{ MUA, 0, "(?(?=(?=(?!(x))a)aa)aaa|(?(?=(?!y)bb)bbb))*k", "abaabbaaabbbaaabbb abaabbaaabbbaaabbbk" }, |
{ MUA, 0, "(?(?=(?=(?!(x))a)aa)aaa|(?(?=(?!y)bb)bbb))*k", "abaabbaaabbbaaabbb abaabbaaabbbaaabbbk" }, |
| 532 |
|
|
| 533 |
/* Set start of match. */ |
/* Set start of match. */ |
| 534 |
{ MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, |
{ MUA, 0, "(?:\\Ka)*aaaab", "aaaaaaaa aaaaaaabb" }, |
| 535 |
{ MUA, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, |
{ MUA, 0, "(?>\\Ka\\Ka)*aaaab", "aaaaaaaa aaaaaaaaaabb" }, |
| 536 |
{ MUA, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, |
{ MUA, 0, "a+\\K(?<=\\Gaa)a", "aaaaaa" }, |
| 579 |
|
|
| 580 |
/* Deep recursion. */ |
/* Deep recursion. */ |
| 581 |
{ MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, |
{ MUA, 0, "((((?:(?:(?:\\w)+)?)*|(?>\\w)+?)+|(?>\\w)?\?)*)?\\s", "aaaaa+ " }, |
| 582 |
{ MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aaa+ " }, |
{ MUA, 0, "(?:((?:(?:(?:\\w*?)+)??|(?>\\w)?|\\w*+)*)+)+?\\s", "aa+ " }, |
| 583 |
|
{ MUA, 0, "((a?)+)+b", "aaaaaaaaaaaaa b" }, |
| 584 |
|
|
| 585 |
|
/* Deep recursion: Stack limit reached. */ |
| 586 |
|
{ MA, 0, "a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?a?aaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaa" }, |
| 587 |
|
{ MA, 0, "(?:a+)+b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, |
| 588 |
|
{ MA, 0, "(?:a+?)+?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, |
| 589 |
|
{ MA, 0, "(?:a*)*b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, |
| 590 |
|
{ MA, 0, "(?:a*?)*?b", "aaaaaaaaaaaaaaaaaaaaaaaa b" }, |
| 591 |
|
|
| 592 |
{ 0, 0, NULL, NULL } |
{ 0, 0, NULL, NULL } |
| 593 |
}; |
}; |
| 594 |
|
|
| 595 |
static void regression_tests(void) |
static int regression_tests(void) |
| 596 |
{ |
{ |
| 597 |
pcre *re; |
pcre *re; |
| 598 |
struct regression_test_case *current = regression_test_cases; |
struct regression_test_case *current = regression_test_cases; |
| 599 |
const char *error; |
const char *error; |
| 600 |
pcre_extra *extra; |
pcre_extra *extra; |
| 601 |
|
int utf8 = 0, ucp = 0; |
| 602 |
int ovector1[32]; |
int ovector1[32]; |
| 603 |
int ovector2[32]; |
int ovector2[32]; |
| 604 |
int return_value1, return_value2; |
int return_value1, return_value2; |
| 605 |
int i, err_offs; |
int i, err_offs; |
| 606 |
int total = 0, succesful = 0; |
int total = 0, succesful = 0; |
| 607 |
int counter = 0; |
int counter = 0; |
| 608 |
|
int disabled_flags = PCRE_BUG; |
| 609 |
|
|
| 610 |
printf("Running JIT regression tests:\n"); |
/* This test compares the behaviour of interpreter and JIT. Although disabling |
| 611 |
|
utf8 or ucp may make tests fail, if the pcre_exec result is the SAME, it is |
| 612 |
|
still considered successful from pcre_jit_test point of view. */ |
| 613 |
|
|
| 614 |
|
pcre_config(PCRE_CONFIG_UTF8, &utf8); |
| 615 |
|
pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp); |
| 616 |
|
if (!utf8) |
| 617 |
|
disabled_flags |= PCRE_UTF8; |
| 618 |
|
if (!ucp) |
| 619 |
|
disabled_flags |= PCRE_UCP; |
| 620 |
|
|
| 621 |
|
printf("Running JIT regression tests with utf8 %s and ucp %s:\n", utf8 ? "enabled" : "disabled", ucp ? "enabled" : "disabled"); |
| 622 |
while (current->pattern) { |
while (current->pattern) { |
| 623 |
/* printf("\nPattern: %s :", current->pattern); */ |
/* printf("\nPattern: %s :\n", current->pattern); */ |
| 624 |
total++; |
total++; |
| 625 |
|
|
| 626 |
error = NULL; |
error = NULL; |
| 627 |
re = pcre_compile(current->pattern, current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | PCRE_BUG), &error, &err_offs, NULL); |
re = pcre_compile(current->pattern, current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | disabled_flags), &error, &err_offs, NULL); |
| 628 |
|
|
| 629 |
if (!re) { |
if (!re) { |
| 630 |
printf("\nCannot compile pattern: %s\n", current->pattern); |
if (utf8 && ucp) |
| 631 |
|
printf("\nCannot compile pattern: %s\n", current->pattern); |
| 632 |
|
else { |
| 633 |
|
/* Some patterns cannot be compiled when either of utf8 |
| 634 |
|
or ucp is disabled. We just skip them. */ |
| 635 |
|
printf("."); |
| 636 |
|
succesful++; |
| 637 |
|
} |
| 638 |
current++; |
current++; |
| 639 |
continue; |
continue; |
| 640 |
} |
} |
| 699 |
succesful++; |
succesful++; |
| 700 |
} |
} |
| 701 |
|
|
| 702 |
if (total == succesful) |
if (total == succesful) { |
| 703 |
printf("\nAll JIT regression tests are successfully passed.\n"); |
printf("\nAll JIT regression tests are successfully passed.\n"); |
| 704 |
else |
return 0; |
| 705 |
|
} else { |
| 706 |
printf("\nSuccessful test ratio: %d%%\n", succesful * 100 / total); |
printf("\nSuccessful test ratio: %d%%\n", succesful * 100 / total); |
| 707 |
|
return 1; |
| 708 |
|
} |
| 709 |
} |
} |
| 710 |
|
|
| 711 |
/* End of pcre_jit_test.c */ |
/* End of pcre_jit_test.c */ |