diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 48dae18fa..93911ac3f 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1906,7 +1906,7 @@ else \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, INT_MAX/10 - 1, 0, &s, errorcodeptr) && + if (read_number(&ptr, ptrend, -1, INT_MAX/10 - 1, ERR61, &s, errorcodeptr) && (s < 10 || oldptr[-1] >= CHAR_8 || s <= (int)cb->bracount)) { if (s > (int)MAX_GROUP_NUMBER) *errorcodeptr = ERR61; @@ -1914,7 +1914,7 @@ else break; } - ptr = oldptr; /* Put the pointer back and fall through */ + if (c <= CHAR_7) ptr = oldptr; /* Put the pointer back for fall through */ } /* Handle a digit following \ when the number is not a back reference, or @@ -1924,6 +1924,12 @@ else if (c >= CHAR_8) break; + /* read_number() could have returned an overflow error, but that is no longer + relevant since we are about to read the number again, but this time as an + octal. */ + + *errorcodeptr = 0; + /* Fall through */ /* \0 always starts an octal number, but we may drop through to here with a diff --git a/testdata/testinput2 b/testdata/testinput2 index 7a836c994..8f85b989c 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4520,6 +4520,12 @@ /(?(1)()\983040\2)/ +/a\800000b/ + +/a\800000000b/ + +/a\8000000000b/ + /(*LIMIT_MATCH=)abc/ /(*CRLF)(*LIMIT_MATCH=)abc/ diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 7c71866b7..a4888a2de 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14718,6 +14718,15 @@ No match /(?(1)()\983040\2)/ Failed: error 161 at offset 14: subpattern number is too big +/a\800000b/ +Failed: error 161 at offset 8: subpattern number is too big + +/a\800000000b/ +Failed: error 161 at offset 11: subpattern number is too big + +/a\8000000000b/ +Failed: error 161 at offset 11: subpattern number is too big + /(*LIMIT_MATCH=)abc/ Failed: error 160 at offset 14: (*VERB) not recognized or malformed