Fix crash due to incorrect pre-pass handling of callouts with string arguments,
and tighten up the callout handling.
This commit is contained in:
parent
5700a2382f
commit
5cd731f314
|
@ -30,6 +30,13 @@ discovered by Karl Skomski with the LLVM fuzzer.
|
||||||
own source module to avoid a circular dependency between src/pcre2_compile.c
|
own source module to avoid a circular dependency between src/pcre2_compile.c
|
||||||
and src/pcre2_study.c
|
and src/pcre2_study.c
|
||||||
|
|
||||||
|
8. A callout with a string argument containing an opening square bracket, for
|
||||||
|
example /(?C$[$)(?<]/, was incorrectly processed and could provoke a buffer
|
||||||
|
overflow. This bug was discovered by Karl Skomski with the LLVM fuzzer.
|
||||||
|
|
||||||
|
9. The handling of callouts during the pre-pass for named group identification
|
||||||
|
has been tightened up.
|
||||||
|
|
||||||
|
|
||||||
Version 10.20 30-June-2015
|
Version 10.20 30-June-2015
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
|
@ -2988,6 +2988,7 @@ static uint32_t scan_for_captures(PCRE2_SPTR *ptrptr, uint32_t options,
|
||||||
compile_block *cb)
|
compile_block *cb)
|
||||||
{
|
{
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
uint32_t delimiter;
|
||||||
uint32_t nest_depth = 0;
|
uint32_t nest_depth = 0;
|
||||||
uint32_t set, unset, *optset;
|
uint32_t set, unset, *optset;
|
||||||
int errorcode = 0;
|
int errorcode = 0;
|
||||||
|
@ -2999,6 +3000,7 @@ BOOL isdupname;
|
||||||
BOOL utf = (options & PCRE2_UTF) != 0;
|
BOOL utf = (options & PCRE2_UTF) != 0;
|
||||||
BOOL negate_class;
|
BOOL negate_class;
|
||||||
PCRE2_SPTR name;
|
PCRE2_SPTR name;
|
||||||
|
PCRE2_SPTR start;
|
||||||
PCRE2_SPTR ptr = *ptrptr;
|
PCRE2_SPTR ptr = *ptrptr;
|
||||||
named_group *ng;
|
named_group *ng;
|
||||||
nest_save *top_nest = NULL;
|
nest_save *top_nest = NULL;
|
||||||
|
@ -3176,7 +3178,6 @@ for (; ptr < cb->end_pattern; ptr++)
|
||||||
default:
|
default:
|
||||||
ptr += 2;
|
ptr += 2;
|
||||||
if (ptr[0] == CHAR_R || /* (?R) */
|
if (ptr[0] == CHAR_R || /* (?R) */
|
||||||
ptr[0] == CHAR_C || /* (?C) */
|
|
||||||
IS_DIGIT(ptr[0]) || /* (?n) */
|
IS_DIGIT(ptr[0]) || /* (?n) */
|
||||||
(ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1]))) break; /* (?-n) */
|
(ptr[0] == CHAR_MINUS && IS_DIGIT(ptr[1]))) break; /* (?-n) */
|
||||||
|
|
||||||
|
@ -3253,6 +3254,56 @@ for (; ptr < cb->end_pattern; ptr++)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Skip over a numerical or string argument for a callout. */
|
||||||
|
|
||||||
|
case CHAR_C:
|
||||||
|
ptr += 2;
|
||||||
|
if (ptr[1] == CHAR_RIGHT_PARENTHESIS) break;
|
||||||
|
if (IS_DIGIT(ptr[1]))
|
||||||
|
{
|
||||||
|
while (IS_DIGIT(ptr[1])) ptr++;
|
||||||
|
if (ptr[1] != CHAR_RIGHT_PARENTHESIS)
|
||||||
|
{
|
||||||
|
errorcode = ERR39;
|
||||||
|
ptr++;
|
||||||
|
goto FAILED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle a string argument */
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
delimiter = 0;
|
||||||
|
for (i = 0; PRIV(callout_start_delims)[i] != 0; i++)
|
||||||
|
{
|
||||||
|
if (*ptr == PRIV(callout_start_delims)[i])
|
||||||
|
{
|
||||||
|
delimiter = PRIV(callout_end_delims)[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delimiter == 0)
|
||||||
|
{
|
||||||
|
errorcode = ERR82;
|
||||||
|
goto FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
start = ptr;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (++ptr >= cb->end_pattern)
|
||||||
|
{
|
||||||
|
errorcode = ERR81;
|
||||||
|
ptr = start; /* To give a more useful message */
|
||||||
|
goto FAILED;
|
||||||
|
}
|
||||||
|
if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2;
|
||||||
|
}
|
||||||
|
while (ptr[0] != delimiter);
|
||||||
|
break;
|
||||||
|
|
||||||
case CHAR_NUMBER_SIGN:
|
case CHAR_NUMBER_SIGN:
|
||||||
ptr += 3;
|
ptr += 3;
|
||||||
while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
|
while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
|
||||||
|
@ -6062,7 +6113,9 @@ for (;; ptr++)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* During the pre-compile phase, we parse the string and update the
|
/* During the pre-compile phase, we parse the string and update the
|
||||||
length. There is no need to generate any code. */
|
length. There is no need to generate any code. (In fact, the string
|
||||||
|
has already been parsed in the pre-pass that looks for named
|
||||||
|
parentheses, but it does no harm to leave this code in.) */
|
||||||
|
|
||||||
if (lengthptr != NULL) /* Only check the string */
|
if (lengthptr != NULL) /* Only check the string */
|
||||||
{
|
{
|
||||||
|
|
|
@ -4331,4 +4331,8 @@ a random value. /Ix
|
||||||
|
|
||||||
/((?x)(*:0))#(?'/
|
/((?x)(*:0))#(?'/
|
||||||
|
|
||||||
|
/(?C$[$)(?<]/
|
||||||
|
|
||||||
|
/(?C$)$)(?<]/
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
|
@ -14476,4 +14476,10 @@ Failed: error 124 at offset 10: unrecognized character after (?<
|
||||||
/((?x)(*:0))#(?'/
|
/((?x)(*:0))#(?'/
|
||||||
Failed: error 124 at offset 15: unrecognized character after (?<
|
Failed: error 124 at offset 15: unrecognized character after (?<
|
||||||
|
|
||||||
|
/(?C$[$)(?<]/
|
||||||
|
Failed: error 124 at offset 10: unrecognized character after (?<
|
||||||
|
|
||||||
|
/(?C$)$)(?<]/
|
||||||
|
Failed: error 124 at offset 10: unrecognized character after (?<
|
||||||
|
|
||||||
# End of testinput2
|
# End of testinput2
|
||||||
|
|
Loading…
Reference in New Issue