summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-09-20 10:46:54 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-09-20 10:46:54 +0000
commit363c1db3479a98e1a894bcd08d4a568bc208d63f (patch)
treea78054d1860b4cd1e9554d3fbd4321dc2afb6a98
parentfb9b53ce56a4eb3430c37e092b2eaa2b26119992 (diff)
downloadpcre-363c1db3479a98e1a894bcd08d4a568bc208d63f.tar.gz
Fix *THEN in condition issue.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@699 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog3
-rw-r--r--pcre_exec.c17
-rw-r--r--testdata/testinput215
-rw-r--r--testdata/testoutput223
4 files changed, 56 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index fde6eb0..b120f00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -48,6 +48,9 @@ Version 8.20 12-Sep-2011
computing a minimum subject length in the presence of *ACCEPT is difficult
(think back references, subroutine calls), and so I have changed the code so
that no minimum is registered for a pattern that contains *ACCEPT.
+
+8. If (*THEN) was present in the first (true) branch of a conditional group,
+ it was not handled as intended.
Version 8.13 16-Aug-2011
diff --git a/pcre_exec.c b/pcre_exec.c
index 03b88bf..38447a9 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -1275,8 +1275,21 @@ for (;;)
{
if (op == OP_SCOND) md->match_function_type = MATCH_CBEGROUP;
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
- if (rrc == MATCH_THEN && md->start_match_ptr == ecode)
- rrc = MATCH_NOMATCH;
+
+ /* If the result is THEN from within the "true" branch of the condition,
+ md->start_match_ptr will point to the original OP_COND, not to the start
+ of the branch, so we have do work to see if it matches. If THEN comes
+ from the "false" branch, md->start_match_ptr does point to OP_ALT. */
+
+ if (rrc == MATCH_THEN)
+ {
+ if (*ecode != OP_ALT)
+ {
+ do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+ ecode -= GET(ecode, 1);
+ }
+ if (md->start_match_ptr == ecode) rrc = MATCH_NOMATCH;
+ }
RRETURN(rrc);
}
else /* Condition false & no alternative */
diff --git a/testdata/testinput2 b/testdata/testinput2
index 453c563..739c48f 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -3733,6 +3733,21 @@ with \Y. ---/
/^.*?(?(?=a)a|bc)/
ba
+/^.*?(?(?=a)a(*THEN)b|c)/
+ ac
+
+/^.*?(?(?=a)a(*THEN)b)c/
+ ac
+
+/^.*?(a(*THEN)b)c/
+ aabc
+
+/^.*?(a(*THEN)b|z)c/
+ aabc
+
+/^.*?(z|a(*THEN)b)c/
+ aabc
+
/-- --/
/-- These studied versions are here because they are not Perl-compatible; the
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index 7cae63c..e13e4df 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -11830,6 +11830,29 @@ No match
ba
0: ba
+/^.*?(?(?=a)a(*THEN)b|c)/
+ ac
+ 0: ac
+
+/^.*?(?(?=a)a(*THEN)b)c/
+ ac
+ 0: ac
+
+/^.*?(a(*THEN)b)c/
+ aabc
+ 0: aabc
+ 1: ab
+
+/^.*?(a(*THEN)b|z)c/
+ aabc
+ 0: aabc
+ 1: ab
+
+/^.*?(z|a(*THEN)b)c/
+ aabc
+ 0: aabc
+ 1: ab
+
/-- --/
/-- These studied versions are here because they are not Perl-compatible; the