Dynamic check of (*MARK) etc name length to avoid the possibility of overflow.

This commit is contained in:
Philip.Hazel 2015-11-03 19:14:31 +00:00
parent 3e24a1b351
commit 4ad83f7103
4 changed files with 114 additions and 86 deletions

View File

@ -260,6 +260,9 @@ as /(?<=(a)(?-1))x/ which have a recursion within a backreference.
75. Give an error in pcre2_substitute() if a match ends before it starts (as a
result of the use of \K).
76. Check the length of the name in (*MARK:xx) etc. dynamically to avoid the
possibility of integer overflow.
Version 10.20 30-June-2015
--------------------------

View File

@ -2875,7 +2875,7 @@ static int
process_verb_name(PCRE2_SPTR *ptrptr, PCRE2_UCHAR **codeptr, int *errorcodeptr,
uint32_t options, BOOL utf, compile_block *cb)
{
int arglen = 0;
int32_t arglen = 0;
BOOL inescq = FALSE;
PCRE2_SPTR ptr = *ptrptr;
PCRE2_UCHAR *code = (codeptr == NULL)? NULL : *codeptr;
@ -2900,8 +2900,8 @@ for (; ptr < cb->end_pattern; ptr++)
{
if (x == CHAR_RIGHT_PARENTHESIS) break;
/* Skip over comments and whitespace in extended mode. Need a loop to handle
whitespace after a comment. */
/* Skip over comments and whitespace in extended mode. Need a loop to
handle whitespace after a comment. */
if ((options & PCRE2_EXTENDED) != 0)
{
@ -2912,8 +2912,8 @@ for (; ptr < cb->end_pattern; ptr++)
ptr++;
while (*ptr != CHAR_NULL)
{
if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
{ /* IS_NEWLINE sets cb->nllen. */
if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
{ /* IS_NEWLINE sets cb->nllen. */
ptr += cb->nllen;
break;
}
@ -2984,6 +2984,12 @@ for (; ptr < cb->end_pattern; ptr++)
}
arglen++;
if ((unsigned int)arglen > MAX_MARK)
{
*errorcodeptr = ERR76;
return -1;
}
}
/* Update the pointers before returning. */
@ -5613,21 +5619,25 @@ for (;; ptr++)
if ((options & PCRE2_ALT_VERBNAMES) == 0)
{
while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
arglen = (int)(ptr - arg);
arglen = 0;
while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS)
{
ptr++; /* Check length as we go */
arglen++; /* along, to avoid the */
if ((unsigned int)arglen > MAX_MARK) /* possibility of overflow. */
{
*errorcodeptr = ERR76;
goto FAILED;
}
}
}
else
{
/* The length check is in process_verb_names() */
arglen = process_verb_name(&ptr, NULL, errorcodeptr, options,
utf, cb);
if (arglen < 0) goto FAILED;
}
if ((unsigned int)arglen > MAX_MARK)
{
*errorcodeptr = ERR76;
goto FAILED;
}
}
if (*ptr != CHAR_RIGHT_PARENTHESIS)

6
testdata/testinput9 vendored
View File

@ -239,9 +239,15 @@
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/mark
XX
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/mark,alt_verbnames
XX
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/mark
XX
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/mark,alt_verbnames
XX
/\u0100/alt_bsux,allow_empty_class,match_unset_backref,dupnames
/[\u0100-\u0200]/alt_bsux,allow_empty_class,match_unset_backref,dupnames

View File

@ -313,11 +313,20 @@ Failed: error 151 at offset 3: octal value is greater than \377 in 8-bit non-UTF
Failed: error 176 at offset 259: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
XX
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF)XX/mark,alt_verbnames
Failed: error 176 at offset 3: name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)
XX
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/mark
XX
0: XX
MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
/(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE)XX/mark,alt_verbnames
XX
0: XX
MK: 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDE
/\u0100/alt_bsux,allow_empty_class,match_unset_backref,dupnames
Failed: error 177 at offset 5: character code point value in \u.... sequence is too large