Skip to content

Commit ce5b604

Browse files
committed
Fix PCRE2_ENDANCHORED behaviour in recursion in pcre2_match(). Fixes #331.
1 parent f5c4eb7 commit ce5b604

File tree

6 files changed

+34
-11
lines changed

6 files changed

+34
-11
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ restrictions on POSIX classes.
146146
pcre2_dfa_match() misbehaved. PCRE2_FIRSTLINE is now ignored for anchored
147147
patterns.
148148

149+
38. If PCRE2_ENDANCHORED was set and the end of the pattern was reached during
150+
a recursion, pcre2_match() misbehaved and gave the wrong match. For example,
151+
the pattern /|a(?0)/ matched against "aaaa".
152+
149153

150154
Version 10.42 11-December-2022
151155
------------------------------

src/pcre2_match.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,18 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
833833
case OP_ACCEPT:
834834
case OP_END:
835835

836+
/* Fail if PCRE2_ENDANCHORED is set and the end of the match is not
837+
the end of the subject. After (*ACCEPT) we fail the entire match (at this
838+
position) but backtrack if we've reached the end of the pattern. This
839+
applies whether or not we are in a recursion. */
840+
841+
if (Feptr < mb->end_subject &&
842+
((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
843+
{
844+
if (Fop == OP_END) RRETURN(MATCH_NOMATCH);
845+
return MATCH_NOMATCH; /* (*ACCEPT) */
846+
}
847+
836848
/* Handle end of a recursion. */
837849

838850
if (Fcurrent_recurse != RECURSE_UNSET)
@@ -871,17 +883,6 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
871883
Fstart_match == mb->start_subject + mb->start_offset)))
872884
RRETURN(MATCH_NOMATCH);
873885

874-
/* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not
875-
the end of the subject. After (*ACCEPT) we fail the entire match (at this
876-
position) but backtrack on reaching the end of the pattern. */
877-
878-
if (Feptr < mb->end_subject &&
879-
((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
880-
{
881-
if (Fop == OP_END) RRETURN(MATCH_NOMATCH);
882-
return MATCH_NOMATCH;
883-
}
884-
885886
/* We have a successful match of the whole pattern. Record the result and
886887
then do a direct return from the function. If there is space in the offset
887888
vector, set any pairs that follow the highest-numbered captured string but

testdata/testinput2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6041,4 +6041,7 @@ a)"xI
60416041
\x0a
60426042
abc\x0adef
60436043

6044+
/|a(?0)/endanchored
6045+
aaaa
6046+
60446047
# End of testinput2

testdata/testinput6

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5039,4 +5039,7 @@
50395039
\x0a
50405040
abc\x0adef
50415041

5042+
/|a(?0)/endanchored
5043+
aaaa
5044+
50425045
# End of testinput6

testdata/testoutput2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17918,6 +17918,10 @@ No match
1791817918
abc\x0adef
1791917919
0: \x0a
1792017920

17921+
/|a(?0)/endanchored
17922+
aaaa
17923+
0: aaaa
17924+
1792117925
# End of testinput2
1792217926
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
1792317927
Error -62: bad serialized data

testdata/testoutput6

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7912,4 +7912,12 @@ Partial match:
79127912
abc\x0adef
79137913
0: \x0a
79147914

7915+
/|a(?0)/endanchored
7916+
aaaa
7917+
0: aaaa
7918+
1: aaa
7919+
2: aa
7920+
3: a
7921+
4:
7922+
79157923
# End of testinput6

0 commit comments

Comments
 (0)