diff --git a/ChangeLog b/ChangeLog index 58ee47f..c25982d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,9 @@ has been tightened up. 10. The quantifier {1} can be ignored, whether greedy, non-greedy, or possessive. This is a very minor optimization. +11. A possessively repeated conditional group that could match an empty string, +for example, /(?(R))*+/, was incorrectly compiled. + Version 10.20 30-June-2015 -------------------------- diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 8563502..6faf649 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -5269,7 +5269,7 @@ for (;; ptr++) conditional, we convert the BRA code to the POS form, and the KET code to KETRPOS. (It turns out to be convenient at runtime to detect this kind of subpattern at both the start and at the end.) The use of special opcodes - makes it possible to reduce greatly the stack usage in pcre_exec(). If + makes it possible to reduce greatly the stack usage in pcre2_match(). If the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. Then, if the minimum number of matches is 1 or 0, cancel the possessive @@ -5333,7 +5333,7 @@ for (;; ptr++) memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen)); code += 1 + LINK_SIZE; nlen += 1 + LINK_SIZE; - *bracode = OP_BRAPOS; + *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS; *code++ = OP_KETRPOS; PUTINC(code, 0, nlen); PUT(bracode, 1, nlen); diff --git a/testdata/testinput2 b/testdata/testinput2 index 2958e6d..a4f3801 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -4339,4 +4339,6 @@ a random value. /Ix /(?C$)$)(?<]/ +/(?(R))*+/B + # End of testinput2 diff --git a/testdata/testoutput2 b/testdata/testoutput2 index 4d1a54c..a356212 100644 --- a/testdata/testoutput2 +++ b/testdata/testoutput2 @@ -14499,4 +14499,17 @@ Failed: error 124 at offset 10: unrecognized character after (?< /(?C$)$)(?<]/ Failed: error 124 at offset 10: unrecognized character after (?< +/(?(R))*+/B +------------------------------------------------------------------ + Bra + Braposzero + SBraPos + SCond + Cond recurse any + Ket + KetRpos + Ket + End +------------------------------------------------------------------ + # End of testinput2