diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-09-20 10:46:54 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-09-20 10:46:54 +0000 |
commit | 363c1db3479a98e1a894bcd08d4a568bc208d63f (patch) | |
tree | a78054d1860b4cd1e9554d3fbd4321dc2afb6a98 | |
parent | fb9b53ce56a4eb3430c37e092b2eaa2b26119992 (diff) | |
download | pcre-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-- | ChangeLog | 3 | ||||
-rw-r--r-- | pcre_exec.c | 17 | ||||
-rw-r--r-- | testdata/testinput2 | 15 | ||||
-rw-r--r-- | testdata/testoutput2 | 23 |
4 files changed, 56 insertions, 2 deletions
@@ -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 |