Add a call to pcre2_dfa_match() to the fuzzer driver.
This commit is contained in:
parent
62564c08fd
commit
72f0c742dd
|
@ -19,6 +19,8 @@ Written by Philip Hazel, October 2016
|
||||||
|
|
||||||
#define MAX_MATCH_SIZE 1000
|
#define MAX_MATCH_SIZE 1000
|
||||||
|
|
||||||
|
#define DFA_WORKSPACE_COUNT 100
|
||||||
|
|
||||||
#define ALLOWED_COMPILE_OPTIONS \
|
#define ALLOWED_COMPILE_OPTIONS \
|
||||||
(PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
|
(PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
|
||||||
PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
|
PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
|
||||||
|
@ -33,9 +35,9 @@ Written by Philip Hazel, October 2016
|
||||||
(PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
|
(PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
|
||||||
PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_HARD| \
|
PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_HARD| \
|
||||||
PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT)
|
PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT)
|
||||||
|
|
||||||
/* This is the callout function. Its only purpose is to halt matching if there
|
/* This is the callout function. Its only purpose is to halt matching if there
|
||||||
are more than 100 callouts, as one way of stopping too much time being spent on
|
are more than 100 callouts, as one way of stopping too much time being spent on
|
||||||
fruitless matches. The callout data is a pointer to the counter. */
|
fruitless matches. The callout data is a pointer to the counter. */
|
||||||
|
|
||||||
static int callout_function(pcre2_callout_block *cb, void *callout_data)
|
static int callout_function(pcre2_callout_block *cb, void *callout_data)
|
||||||
|
@ -44,9 +46,9 @@ static int callout_function(pcre2_callout_block *cb, void *callout_data)
|
||||||
*((uint32_t *)callout_data) += 1;
|
*((uint32_t *)callout_data) += 1;
|
||||||
return (*((uint32_t *)callout_data) > 100)? PCRE2_ERROR_CALLOUT : 0;
|
return (*((uint32_t *)callout_data) > 100)? PCRE2_ERROR_CALLOUT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Putting in this apparently unnecessary prototype prevents gcc from giving a
|
/* Putting in this apparently unnecessary prototype prevents gcc from giving a
|
||||||
"no previous prototype" warning when compiling at high warning level. */
|
"no previous prototype" warning when compiling at high warning level. */
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(const unsigned char *, size_t);
|
int LLVMFuzzerTestOneInput(const unsigned char *, size_t);
|
||||||
|
|
||||||
|
@ -59,12 +61,13 @@ uint32_t match_options;
|
||||||
pcre2_match_data *match_data = NULL;
|
pcre2_match_data *match_data = NULL;
|
||||||
pcre2_match_context *match_context = NULL;
|
pcre2_match_context *match_context = NULL;
|
||||||
size_t match_size;
|
size_t match_size;
|
||||||
|
int dfa_workspace[DFA_WORKSPACE_COUNT];
|
||||||
int r1, r2;
|
int r1, r2;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (size < 1) return 0;
|
if (size < 1) return 0;
|
||||||
|
|
||||||
/* Limiting the length of the subject for matching stops fruitless searches
|
/* Limiting the length of the subject for matching stops fruitless searches
|
||||||
in large trees taking too much time. */
|
in large trees taking too much time. */
|
||||||
|
|
||||||
match_size = (size > MAX_MATCH_SIZE)? MAX_MATCH_SIZE : size;
|
match_size = (size > MAX_MATCH_SIZE)? MAX_MATCH_SIZE : size;
|
||||||
|
@ -134,7 +137,7 @@ for (i = 0; i < 2; i++)
|
||||||
|
|
||||||
code = pcre2_compile((PCRE2_SPTR)data, (PCRE2_SIZE)size, compile_options,
|
code = pcre2_compile((PCRE2_SPTR)data, (PCRE2_SIZE)size, compile_options,
|
||||||
&errorcode, &erroroffset, NULL);
|
&errorcode, &erroroffset, NULL);
|
||||||
|
|
||||||
/* Compilation succeeded */
|
/* Compilation succeeded */
|
||||||
|
|
||||||
if (code != NULL)
|
if (code != NULL)
|
||||||
|
@ -169,8 +172,8 @@ for (i = 0; i < 2; i++)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
(void)pcre2_set_match_limit(match_context, 100);
|
(void)pcre2_set_match_limit(match_context, 100);
|
||||||
(void)pcre2_set_depth_limit(match_context, 100);
|
(void)pcre2_set_depth_limit(match_context, 100);
|
||||||
(void)pcre2_set_callout(match_context, callout_function, &callout_count);
|
(void)pcre2_set_callout(match_context, callout_function, &callout_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Match twice, with and without options */
|
/* Match twice, with and without options */
|
||||||
|
@ -195,6 +198,42 @@ for (i = 0; i < 2; i++)
|
||||||
errorcode = pcre2_match(code, (PCRE2_SPTR)data, (PCRE2_SIZE)match_size, 0,
|
errorcode = pcre2_match(code, (PCRE2_SPTR)data, (PCRE2_SIZE)match_size, 0,
|
||||||
match_options, match_data, match_context);
|
match_options, match_data, match_context);
|
||||||
|
|
||||||
|
#ifdef STANDALONE
|
||||||
|
if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
|
||||||
|
{
|
||||||
|
unsigned char buffer[256];
|
||||||
|
pcre2_get_error_message(errorcode, buffer, 256);
|
||||||
|
printf("Match failed: error %d: %s\n", errorcode, buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
match_options = 0; /* For second time */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Match with DFA twice, with and without options */
|
||||||
|
|
||||||
|
match_options = save_match_options & ~PCRE2_NO_JIT;
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
#ifdef STANDALONE
|
||||||
|
printf("DFA match options %.8x", match_options);
|
||||||
|
printf("%s%s%s%s%s%s%s%s%s\n",
|
||||||
|
((match_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
|
||||||
|
((match_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
|
||||||
|
((match_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
|
||||||
|
((match_options & PCRE2_NOTBOL) != 0)? ",notbol" : "",
|
||||||
|
((match_options & PCRE2_NOTEMPTY) != 0)? ",notempty" : "",
|
||||||
|
((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? ",notempty_atstart" : "",
|
||||||
|
((match_options & PCRE2_NOTEOL) != 0)? ",noteol" : "",
|
||||||
|
((match_options & PCRE2_PARTIAL_HARD) != 0)? ",partial_hard" : "",
|
||||||
|
((match_options & PCRE2_PARTIAL_SOFT) != 0)? ",partial_soft" : "");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
callout_count = 0;
|
||||||
|
errorcode = pcre2_dfa_match(code, (PCRE2_SPTR)data,
|
||||||
|
(PCRE2_SIZE)match_size, 0, match_options, match_data, match_context,
|
||||||
|
dfa_workspace, DFA_WORKSPACE_COUNT);
|
||||||
|
|
||||||
#ifdef STANDALONE
|
#ifdef STANDALONE
|
||||||
if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
|
if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
|
||||||
{
|
{
|
||||||
|
@ -210,7 +249,7 @@ for (i = 0; i < 2; i++)
|
||||||
match_options = save_match_options; /* Reset for the second compile */
|
match_options = save_match_options; /* Reset for the second compile */
|
||||||
pcre2_code_free(code);
|
pcre2_code_free(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compilation failed */
|
/* Compilation failed */
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -253,30 +292,30 @@ for (i = 1; i < argc; i++)
|
||||||
size_t readsize;
|
size_t readsize;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
/* Handle a literal string. Copy to an exact size buffer so that checks for
|
/* Handle a literal string. Copy to an exact size buffer so that checks for
|
||||||
overrunning work. */
|
overrunning work. */
|
||||||
|
|
||||||
if (argv[i][0] == '=')
|
if (argv[i][0] == '=')
|
||||||
{
|
{
|
||||||
readsize = strlen(argv[i]) - 1;
|
readsize = strlen(argv[i]) - 1;
|
||||||
printf("------ <Literal> ------\n");
|
printf("------ <Literal> ------\n");
|
||||||
printf("Length = %lu\n", readsize);
|
printf("Length = %lu\n", readsize);
|
||||||
printf("%.*s\n", (int)readsize, argv[i]+1);
|
printf("%.*s\n", (int)readsize, argv[i]+1);
|
||||||
buffer = (unsigned char *)malloc(readsize);
|
buffer = (unsigned char *)malloc(readsize);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
printf("** Failed to allocate %lu bytes of memory\n", readsize);
|
printf("** Failed to allocate %lu bytes of memory\n", readsize);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy(buffer, argv[i]+1, readsize);
|
memcpy(buffer, argv[i]+1, readsize);
|
||||||
LLVMFuzzerTestOneInput(buffer, readsize);
|
LLVMFuzzerTestOneInput(buffer, readsize);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle a string given in a file */
|
/* Handle a string given in a file */
|
||||||
|
|
||||||
f = fopen(argv[i], "rb");
|
f = fopen(argv[i], "rb");
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue