Skip to content

Commit

Permalink
Fix 32-bit quantifier following a character larger than the maximum U…
Browse files Browse the repository at this point in the history
…TF character.
  • Loading branch information
PhilipHazel committed Nov 19, 2023
1 parent 9783ca9 commit c130612
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 3 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ consistency with OP_VREVERSE.
40. In some legacy environments with a pre C99 snprintf, pcre2_regerror could
return an incorrect value when the provided buffer was too small.

41. Applied pull request #342 which adds sanity checks for ctype functions and
locks out any accidental sign-extension.

42. In the 32-bit library, in non-UTF mode, a quantifier that followed a
literal character with a value greater than or equal to 0x80000000u caused
undefined behaviour.


Version 10.42 11-December-2022
------------------------------
Expand Down
11 changes: 8 additions & 3 deletions src/pcre2_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -2781,6 +2781,7 @@ uint32_t *verbstartptr = NULL;
uint32_t *previous_callout = NULL;
uint32_t *parsed_pattern = cb->parsed_pattern;
uint32_t *parsed_pattern_end = cb->parsed_pattern_end;
uint32_t *this_parsed_item = NULL;
uint32_t meta_quantifier = 0;
uint32_t add_after_mark = 0;
uint32_t xoptions = cb->cx->extra_options;
Expand Down Expand Up @@ -2866,10 +2867,11 @@ while (ptr < ptrend)
uint32_t xset, xunset, *xoptset;
uint32_t terminator;
uint32_t prev_meta_quantifier;
uint32_t *prev_parsed_item = this_parsed_item;
BOOL prev_okquantifier;
PCRE2_SPTR tempptr;
PCRE2_SIZE offset;

if (parsed_pattern >= parsed_pattern_end)
{
errorcode = ERR63; /* Internal error (parsed pattern overflow) */
Expand All @@ -2881,6 +2883,10 @@ while (ptr < ptrend)
errorcode = ERR19;
goto FAILED; /* Parentheses too deeply nested */
}

/* Remember where this item started */

this_parsed_item = parsed_pattern;

/* Get next input character, save its position for callout handling. */

Expand Down Expand Up @@ -3173,7 +3179,6 @@ while (ptr < ptrend)
continue; /* Next character in pattern */
}


/* Process the next item in the main part of a pattern. */

switch(c)
Expand Down Expand Up @@ -3450,7 +3455,7 @@ while (ptr < ptrend)
wrapping it in non-capturing brackets, but we have to allow for a preceding
(*MARK) for when (*ACCEPT) has an argument. */

if (parsed_pattern[-1] == META_ACCEPT)
if (*prev_parsed_item == META_ACCEPT)
{
uint32_t *p;
for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0];
Expand Down
6 changes: 6 additions & 0 deletions testdata/testinput12
Original file line number Diff line number Diff line change
Expand Up @@ -560,4 +560,10 @@

# ----------------------------------------------------

# Quantifier after a literal that has the value of META_ACCEPT (not UTF). This
# fails in 16-bit mode, but is OK for 32-bit.

/\x{802a0000}*/
\x{802a0000}\x{802a0000}

# End of testinput12
7 changes: 7 additions & 0 deletions testdata/testoutput12-16
Original file line number Diff line number Diff line change
Expand Up @@ -1803,4 +1803,11 @@ No match

# ----------------------------------------------------

# Quantifier after a literal that has the value of META_ACCEPT (not UTF). This
# fails in 16-bit mode, but is OK for 32-bit.

/\x{802a0000}*/
Failed: error 134 at offset 11: character code point value in \x{} or \o{} is too large
\x{802a0000}\x{802a0000}

# End of testinput12
7 changes: 7 additions & 0 deletions testdata/testoutput12-32
Original file line number Diff line number Diff line change
Expand Up @@ -1801,4 +1801,11 @@ No match

# ----------------------------------------------------

# Quantifier after a literal that has the value of META_ACCEPT (not UTF). This
# fails in 16-bit mode, but is OK for 32-bit.

/\x{802a0000}*/
\x{802a0000}\x{802a0000}
0: \x{802a0000}\x{802a0000}

# End of testinput12

0 comments on commit c130612

Please sign in to comment.