diff --git a/ChangeLog b/ChangeLog index 19e0230..5678765 100644 --- a/ChangeLog +++ b/ChangeLog @@ -79,6 +79,9 @@ copied). pattern one further code unit was read. (h) An unterminated number after \g' could cause reading beyond the pattern. + + (i) An insufficient memory size was being computed for compiling with + PCRE2_AUTO_CALLOUT. 4. Back references are now permitted in lookbehind assertions when there are no duplicated group numbers (that is, (?| has not been used), and, if the diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 850ba7b..2519147 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -2146,6 +2146,7 @@ uint32_t class_range_state; uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */ uint32_t *previous_callout = NULL; uint32_t *parsed_pattern = cb->parsed_pattern; +uint32_t *parsed_pattern_end = cb->parsed_pattern_end; uint32_t meta_quantifier = 0; uint16_t nest_depth = 0; int after_manual_callout = 0; @@ -2188,6 +2189,12 @@ while (ptr < ptrend) PCRE2_SPTR tempptr; PCRE2_SPTR thisptr; PCRE2_SIZE offset; + + if (parsed_pattern >= parsed_pattern_end) + { + errorcode = ERR63; /* Internal error (parsed pattern overflow) */ + goto FAILED; + } if (nest_depth > cb->cx->parens_nest_limit) { @@ -9158,7 +9165,7 @@ used. */ parsed_size_needed = patlen - skipatstart + big32count; if ((options & PCRE2_AUTO_CALLOUT) != 0) - parsed_size_needed = (parsed_size_needed + 1) * 4; + parsed_size_needed = (parsed_size_needed + 1) * 5; if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE) { @@ -9171,7 +9178,8 @@ if (parsed_size_needed >= PARSED_PATTERN_DEFAULT_SIZE) } cb.parsed_pattern = heap_parsed_pattern; } - +cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1; + /* Do the parsing scan. */ errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb); diff --git a/src/pcre2_error.c b/src/pcre2_error.c index c09d3d9..83c647d 100644 --- a/src/pcre2_error.c +++ b/src/pcre2_error.c @@ -138,7 +138,7 @@ static const unsigned char compile_error_texts[] = "(*VERB) not recognized or malformed\0" "group number is too big\0" "subpattern name expected\0" - "SPARE ERROR\0" + "internal error: parsed pattern overflow\0" "non-octal character in \\o{} (closing brace missing?)\0" /* 65 */ "different names for subpatterns of the same number are not allowed\0" diff --git a/src/pcre2_fuzzsupport.c b/src/pcre2_fuzzsupport.c index 2c0e56a..ef52908 100644 --- a/src/pcre2_fuzzsupport.c +++ b/src/pcre2_fuzzsupport.c @@ -65,11 +65,11 @@ reason to disallow UTF and UCP. Force PCRE2_NEVER_BACKSLASH_C to be set because \C in random patterns is highly likely to cause a crash. */ compile_options = - ((uint32_t)((r1 << 16) | (r2 & 0xffff)) & ALLOWED_COMPILE_OPTIONS) | + ((((uint32_t)r1 << 16) | ((uint32_t)r2 & 0xffff)) & ALLOWED_COMPILE_OPTIONS) | PCRE2_NEVER_BACKSLASH_C; match_options = - ((uint32_t)((r1 << 16) | (r2 & 0xffff)) & ALLOWED_MATCH_OPTIONS); + ((((uint32_t)r1 << 16) | ((uint32_t)r2 & 0xffff)) & ALLOWED_MATCH_OPTIONS); /* Do the compile with and without the options, and after a successful compile, likewise do the match with and without the options. */ diff --git a/src/pcre2_intmodedep.h b/src/pcre2_intmodedep.h index 0579bd6..843204b 100644 --- a/src/pcre2_intmodedep.h +++ b/src/pcre2_intmodedep.h @@ -713,6 +713,7 @@ typedef struct compile_block { uint32_t bracount; /* Count of capturing parentheses */ uint32_t lastcapture; /* Last capture encountered */ uint32_t *parsed_pattern; /* Parsed pattern buffer */ + uint32_t *parsed_pattern_end; /* Parsed pattern should not get here */ uint32_t *groupinfo; /* Group info vector */ uint32_t top_backref; /* Maximum back reference */ uint32_t backref_map; /* Bitmap of low back refs */