Skip to content

Commit

Permalink
pcre2_compile: advance erroroffset to end of number on overflow
Browse files Browse the repository at this point in the history
Make the reported erroroffset from a failure originating in
read_number() more acurate.

While at it, do some cleanup on recent code that made the issue
more evident.
  • Loading branch information
carenas committed Sep 18, 2024
1 parent 0333a78 commit e3134e7
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 15 deletions.
14 changes: 9 additions & 5 deletions src/pcre2_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1351,7 +1351,7 @@ result must be greater than zero.
allow_sign if < 0, sign not allowed; if >= 0, sign is relative to this
max_value the largest number allowed;
you must not pass a value for max_value larger than
INT_MAX/10 - 1 because read_number() relies on max_value to
INT_MAX/10 - 1 because this function relies on max_value to
avoid integer overflow
max_error the error to give for an over-large number
intptr where to put the result
Expand All @@ -1371,6 +1371,8 @@ uint32_t n = 0;
PCRE2_SPTR ptr = *ptrptr;
BOOL yield = FALSE;

PCRE2_ASSERT(max_value <= INT_MAX/10 - 1);

*errorcodeptr = 0;

if (allow_sign >= 0 && ptr < ptrend)
Expand All @@ -1395,6 +1397,7 @@ while (ptr < ptrend && IS_DIGIT(*ptr))
if (n > max_value)
{
*errorcodeptr = max_error;
while (ptr < ptrend && IS_DIGIT(*ptr)) ptr++;
goto EXIT;
}
}
Expand Down Expand Up @@ -1904,18 +1907,19 @@ else

/* As we know we are at a digit, the only possible error from
read_number() is a number that is too large to be a group number. In this
case we treat the group number as too-large (since it may be larger than
INT_MAX we cannot return it for the caller to check).
case, since we are otherwise not setting errorcodeptr to an error, we
assign a bogus value of INT_MAX to the returned value so it can get that
error before falling through.
\1 to \9 are always back references. \8x and \9x are too; \1x to \7x
are octal escapes if there are not that many previous captures. */

if (!read_number(&ptr, ptrend, -1, MAX_GROUP_NUMBER, 0, &s, errorcodeptr))
s = INT_MAX;

if (s < 10 || oldptr[-1] >= CHAR_8 || (unsigned)s <= bracount)
if (s < 10 || c >= CHAR_8 || (unsigned)s <= bracount)
{
if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61;
if ((unsigned)s > MAX_GROUP_NUMBER) *errorcodeptr = ERR61;
else escape = -s; /* Indicates a back reference */
break;
}
Expand Down
20 changes: 10 additions & 10 deletions testdata/testoutput2
Original file line number Diff line number Diff line change
Expand Up @@ -5506,13 +5506,13 @@ Subject length lower bound = 4
No match

/a{11111111111111111111}/I
Failed: error 105 at offset 8: number too big in {} quantifier
Failed: error 105 at offset 22: number too big in {} quantifier

/(){64294967295}/I
Failed: error 105 at offset 9: number too big in {} quantifier
Failed: error 105 at offset 14: number too big in {} quantifier

/(){2,4294967295}/I
Failed: error 105 at offset 11: number too big in {} quantifier
Failed: error 105 at offset 15: number too big in {} quantifier

"(?i:a)(?i:b)(?i:c)(?i:d)(?i:e)(?i:f)(?i:g)(?i:h)(?i:i)(?i:j)(k)(?i:l)A\1B"I
Capture group count = 1
Expand Down Expand Up @@ -8374,7 +8374,7 @@ No match
Failed: error 166 at offset 7: (*MARK) must have an argument

/\g6666666666/
Failed: error 161 at offset 7: subpattern number is too big
Failed: error 161 at offset 12: subpattern number is too big

/[\g6666666666]/B
------------------------------------------------------------------
Expand Down Expand Up @@ -14531,7 +14531,7 @@ Failed: error 162 at offset 4: subpattern name expected
"(?J:(?|(?'R')(\k'R')|((?'R'))))"

/(?<=|(\,\$(?73591620449005828816)\xa8.{7}){6}\x09)/
Failed: error 161 at offset 17: subpattern number is too big
Failed: error 161 at offset 32: subpattern number is too big

/^(?:(?(1)x|)+)+$()/B
------------------------------------------------------------------
Expand Down Expand Up @@ -14722,7 +14722,7 @@ No match
0: ab

/(?(8000000000/
Failed: error 161 at offset 8: subpattern number is too big
Failed: error 161 at offset 13: subpattern number is too big

/((?(R8000000000)))/
Failed: error 161 at offset 9: subpattern number is too big
Expand All @@ -14733,7 +14733,7 @@ Failed: error 161 at offset 9: subpattern number is too big
No match

/(?(1)()\983040\2)/
Failed: error 161 at offset 13: subpattern number is too big
Failed: error 161 at offset 14: subpattern number is too big

/(*LIMIT_MATCH=)abc/
Failed: error 160 at offset 14: (*VERB) not recognized or malformed
Expand Down Expand Up @@ -19105,15 +19105,15 @@ No match

# larger than GROUP_MAX, smaller than INT_MAX
/a\800000b/
Failed: error 161 at offset 7: subpattern number is too big
Failed: error 161 at offset 8: subpattern number is too big

# coming up on INT_MAX... (used to succeed with \8 being literal 8)
/a\800000000b/
Failed: error 161 at offset 7: subpattern number is too big
Failed: error 161 at offset 11: subpattern number is too big

# over INT_MAX (used to succeed with \8 being literal 8)
/a\8000000000b/
Failed: error 161 at offset 7: subpattern number is too big
Failed: error 161 at offset 12: subpattern number is too big

# End of testinput2
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
Expand Down

0 comments on commit e3134e7

Please sign in to comment.