Fix bad compilation of a possessively repeated conditional that could match an

empty string.
This commit is contained in:
Philip.Hazel 2015-07-17 15:11:45 +00:00
parent c31df29130
commit c1f8a7dfb3
4 changed files with 20 additions and 2 deletions

View File

@ -40,6 +40,9 @@ has been tightened up.
10. The quantifier {1} can be ignored, whether greedy, non-greedy, or 10. The quantifier {1} can be ignored, whether greedy, non-greedy, or
possessive. This is a very minor optimization. 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 Version 10.20 30-June-2015
-------------------------- --------------------------

View File

@ -5269,7 +5269,7 @@ for (;; ptr++)
conditional, we convert the BRA code to the POS form, and the KET code to 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 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 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. 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 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)); memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen));
code += 1 + LINK_SIZE; code += 1 + LINK_SIZE;
nlen += 1 + LINK_SIZE; nlen += 1 + LINK_SIZE;
*bracode = OP_BRAPOS; *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
*code++ = OP_KETRPOS; *code++ = OP_KETRPOS;
PUTINC(code, 0, nlen); PUTINC(code, 0, nlen);
PUT(bracode, 1, nlen); PUT(bracode, 1, nlen);

2
testdata/testinput2 vendored
View File

@ -4339,4 +4339,6 @@ a random value. /Ix
/(?C$)$)(?<]/ /(?C$)$)(?<]/
/(?(R))*+/B
# End of testinput2 # End of testinput2

13
testdata/testoutput2 vendored
View File

@ -14499,4 +14499,17 @@ Failed: error 124 at offset 10: unrecognized character after (?<
/(?C$)$)(?<]/ /(?C$)$)(?<]/
Failed: error 124 at offset 10: unrecognized character after (?< 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 # End of testinput2