diff --git a/ChangeLog b/ChangeLog index 2668877..bcaf5e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -69,6 +69,9 @@ the LLVM fuzzer. 18. A conditional group with only one branch has an implicit empty alternative branch and must therefore be treated as potentially matching an empty string. +19. If (?R was followed by - or + incorrect behaviour happened instead of a +diagnostic. This bug was discovered by Karl Skomski with the LLVM fuzzer. + Version 10.20 30-June-2015 -------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 9f1296d..79b8c80 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -2583,8 +2583,8 @@ when Perl does, I think. A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not. It seems that the appearance of a nested POSIX class supersedes an apparent external class. For example, [:a[:digit:]b:] matches "a", "b", ":", or -a digit. This is handled by returning FALSE if the start of a new group with -the same terminator is encountered, since the next closing sequence must close +a digit. This is handled by returning FALSE if the start of a new group with +the same terminator is encountered, since the next closing sequence must close the nested group, not the outer one. In Perl, unescaped square brackets may also appear as part of class names. For @@ -3282,7 +3282,7 @@ for (; ptr < cb->end_pattern; ptr++) /* Handle a string argument */ else - { + { ptr++; delimiter = 0; for (i = 0; PRIV(callout_start_delims)[i] != 0; i++) @@ -3293,13 +3293,13 @@ for (; ptr < cb->end_pattern; ptr++) break; } } - + if (delimiter == 0) { errorcode = ERR82; goto FAILED; } - + start = ptr; do { @@ -3312,8 +3312,8 @@ for (; ptr < cb->end_pattern; ptr++) if (ptr[0] == delimiter && ptr[1] == delimiter) ptr += 2; } while (ptr[0] != delimiter); - } - + } + /* Check terminating ) */ if (ptr[1] != CHAR_RIGHT_PARENTHESIS) @@ -5324,12 +5324,12 @@ for (;; ptr++) scode += GET(scode, 1); } while (*scode == OP_ALT); - - /* A conditional group with only one branch has an implicit empty + + /* A conditional group with only one branch has an implicit empty alternative branch. */ if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT) - *bracode = OP_SCOND; + *bracode = OP_SCOND; } /* Handle possessive quantifiers. */ @@ -6394,9 +6394,14 @@ for (;; ptr++) /* ------------------------------------------------------------ */ - case CHAR_R: /* Recursion */ - ptr++; /* Same as (?0) */ - /* Fall through */ + case CHAR_R: /* Recursion, same as (?0) */ + recno = 0; + if (*(++ptr) != CHAR_RIGHT_PARENTHESIS) + { + *errorcodeptr = ERR29; + goto FAILED; + } + goto HANDLE_RECURSION; /* ------------------------------------------------------------ */ diff --git a/testdata/testinput2 b/testdata/testinput2 index 1a4df08..fbe8a6a 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4354,4 +4354,6 @@ a random value. /Ix /()(?(R)0)*+/B +/(?R-:(?