summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-11-18 11:07:14 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-11-18 11:07:14 +0000
commit2665f146c5250f8972d562a368b21e4f6350f4df (patch)
tree8ca0c452209a1c015d8279df4865fb7ff72b2297
parent0c3ee8182f352dc0aeecb56b3e2ab353891da04d (diff)
downloadpcre-2665f146c5250f8972d562a368b21e4f6350f4df.tar.gz
Fix problem with possessively repeated groups with minima greater than one.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@750 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog5
-rw-r--r--pcre_compile.c20
-rw-r--r--testdata/testinput114
-rw-r--r--testdata/testoutput123
4 files changed, 54 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 7d3f451..890de84 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -36,6 +36,11 @@ Version 8.21
8. A possessively repeated conditional subpattern such as (?(?=c)c|d)++ was
being incorrectly compiled and would have given unpredicatble results.
+
+9. A possessively repeated subpattern with minimum repeat count greater than
+ one behaved incorrectly. For example, (A){2,}+ behaved as if it was
+ (A)(A)++ which meant that, after a subsequent mismatch, backtracking into
+ the first (A) could occur when it should not.
Version 8.20 21-Oct-2011
diff --git a/pcre_compile.c b/pcre_compile.c
index c66cff1..10c136b 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -4994,9 +4994,13 @@ for (;; ptr++)
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
- the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. Then
- cancel the possessive flag so that the default action below, of wrapping
- everything inside atomic brackets, does not happen. */
+ 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
+ flag so that the default action below, of wrapping everything inside
+ atomic brackets, does not happen. When the minimum is greater than 1,
+ there will be earlier copies of the group, and so we still have to wrap
+ the whole thing. */
else
{
@@ -5068,10 +5072,10 @@ for (;; ptr++)
}
/* If the minimum is zero, mark it as possessive, then unset the
- possessive flag. */
+ possessive flag when the minimum is 0 or 1. */
if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
- possessive_quantifier = FALSE;
+ if (repeat_min < 2) possessive_quantifier = FALSE;
}
/* Non-possessive quantifier */
@@ -5103,9 +5107,9 @@ for (;; ptr++)
notation is just syntactic sugar, taken from Sun's Java package, but the
special opcodes can optimize it.
- Possessively repeated subpatterns have already been handled in the code
- just above, so possessive_quantifier is always FALSE for them at this
- stage.
+ Some (but not all) possessively repeated subpatterns have already been
+ completely handled in the code just above. For them, possessive_quantifier
+ is always FALSE at this stage.
Note that the repeated item starts at tempcode, not at previous, which
might be the first part of a string whose (former) last char we repeated.
diff --git a/testdata/testinput1 b/testdata/testinput1
index 5c65ed6..61fd20b 100644
--- a/testdata/testinput1
+++ b/testdata/testinput1
@@ -4291,4 +4291,18 @@
/(?(?=c)c|d)*+Y/
XcccddYX
+/^(a{2,3}){2,}+a/
+ aaaaaaa
+ ** Failers
+ aaaaaa
+ aaaaaaaaa
+
+/^(a{2,3})++a/
+ ** Failers
+ aaaaaa
+
+/^(a{2,3})*+a/
+ ** Failers
+ aaaaaa
+
/-- End of testinput1 --/
diff --git a/testdata/testoutput1 b/testdata/testoutput1
index 54c0bf2..2557fe2 100644
--- a/testdata/testoutput1
+++ b/testdata/testoutput1
@@ -7012,4 +7012,27 @@ No match
XcccddYX
0: cccddY
+/^(a{2,3}){2,}+a/
+ aaaaaaa
+ 0: aaaaaaa
+ 1: aaa
+ ** Failers
+No match
+ aaaaaa
+No match
+ aaaaaaaaa
+No match
+
+/^(a{2,3})++a/
+ ** Failers
+No match
+ aaaaaa
+No match
+
+/^(a{2,3})*+a/
+ ** Failers
+No match
+ aaaaaa
+No match
+
/-- End of testinput1 --/