diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2010-01-02 12:40:07 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2010-01-02 12:40:07 +0000 |
commit | 1d5dad0b7e2087e3667cbb402e74636970cea259 (patch) | |
tree | cc237e32be27ed3608f6de72a86aba82e1e7d4db | |
parent | d70bdebcc62f48ae54bb2d7e7216d629bdc5dfcc (diff) | |
download | pcre-1d5dad0b7e2087e3667cbb402e74636970cea259.tar.gz |
Fix bugs relating to the use of (*SKIP) etc in assertions.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@473 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | pcre_dfa_exec.c | 6 | ||||
-rw-r--r-- | pcre_exec.c | 11 | ||||
-rw-r--r-- | testdata/testinput11 | 21 | ||||
-rw-r--r-- | testdata/testinput7 | 18 | ||||
-rw-r--r-- | testdata/testoutput11 | 30 | ||||
-rw-r--r-- | testdata/testoutput7 | 26 |
7 files changed, 125 insertions, 10 deletions
@@ -5,17 +5,28 @@ Version 8.01 11-Dec-09 ---------------------- 1. If a pattern contained a conditional subpattern with only one branch (in - particular, this includes all (DEFINE) patterns), a call to pcre_study() - computed the wrong minimum data length (which is of course zero for such + particular, this includes all (DEFINE) patterns), a call to pcre_study() + computed the wrong minimum data length (which is of course zero for such subpatterns). - -2. For patterns such as (?i)a(?-i)b|c where an option setting at the start of + +2. For patterns such as (?i)a(?-i)b|c where an option setting at the start of the pattern is reset in the first branch, pcre_compile() failed with "internal error: code overflow at offset...". This happened only when - the reset was to the original external option setting. (An optimization - abstracts leading options settings into an external setting, which was the + the reset was to the original external option setting. (An optimization + abstracts leading options settings into an external setting, which was the cause of this.) +3. A pattern such as ^(?!a(*SKIP)b) where a negative assertion contained one + of the verbs SKIP, PRUNE, or COMMIT, did not work correctly. When the + assertion pattern did not match (meaning that the assertion was true), it + was incorrectly treated as false if the SKIP had been reached during the + matching. This also applied to assertions used as conditions. + +4. If an item that is not supported by pcre_dfa_exec() was encountered in an + assertion subpattern, including such a pattern used as a condition, + unpredictable results occurred, instead of the error return + PCRE_ERROR_DFA_UITEM. + Version 8.00 19-Oct-09 ---------------------- diff --git a/pcre_dfa_exec.c b/pcre_dfa_exec.c index a4a0ae2..5c1875a 100644 --- a/pcre_dfa_exec.c +++ b/pcre_dfa_exec.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language (but see below for why this module is different). Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2010 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -2298,7 +2298,8 @@ for (;;) ims, /* the current ims flags */ rlevel, /* function recursion level */ recursing); /* pass on regex recursion */ - + + if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); } } @@ -2389,6 +2390,7 @@ for (;;) rlevel, /* function recursion level */ recursing); /* pass on regex recursion */ + if (rc == PCRE_ERROR_DFA_UITEM) return rc; if ((rc >= 0) == (condcode == OP_ASSERT || condcode == OP_ASSERTBACK)) { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); } diff --git a/pcre_exec.c b/pcre_exec.c index fb27e17..fd6866b 100644 --- a/pcre_exec.c +++ b/pcre_exec.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2009 University of Cambridge + Copyright (c) 1997-2010 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -1133,7 +1133,9 @@ for (;;) offset_top = md->end_offset_top; continue; - /* Negative assertion: all branches must fail to match */ + /* Negative assertion: all branches must fail to match. Encountering SKIP, + PRUNE, or COMMIT means we must assume failure without checking subsequent + branches. */ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: @@ -1142,6 +1144,11 @@ for (;;) RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0, RM5); if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH); + if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT) + { + do ecode += GET(ecode,1); while (*ecode == OP_ALT); + break; + } if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); ecode += GET(ecode,1); } diff --git a/testdata/testinput11 b/testdata/testinput11 index ad896fd..501ac3c 100644 --- a/testdata/testinput11 +++ b/testdata/testinput11 @@ -336,4 +336,25 @@ /(?<pn> \( ( [^()]++ | (?&pn) )* \) )/x (ab(cd)ef) +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?=a(*ACCEPT)b)/ + ac + +/^(?(?!a(*SKIP)b))/ + ac + /-- End of testinput11 --/ diff --git a/testdata/testinput7 b/testdata/testinput7 index 710d9ee..5d27311 100644 --- a/testdata/testinput7 +++ b/testdata/testinput7 @@ -4542,4 +4542,22 @@ CAD BAD +/^(?!a(*SKIP)b)/ + ac + +/^(?=a(*SKIP)b|ac)/ + ** Failers + ac + +/^(?=a(*THEN)b|ac)/ + ac + +/^(?=a(*PRUNE)b)/ + ab + ** Failers + ac + +/^(?(?!a(*SKIP)b))/ + ac + /-- End of testinput7 --/ diff --git a/testdata/testoutput11 b/testdata/testoutput11 index e901e0b..e5d3df7 100644 --- a/testdata/testoutput11 +++ b/testdata/testoutput11 @@ -712,4 +712,34 @@ No match 1: (ab(cd)ef) 2: ef +/^(?!a(*SKIP)b)/ + ac + 0: + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +No match + +/^(?=a(*THEN)b|ac)/ + ac + 0: + +/^(?=a(*PRUNE)b)/ + ab + 0: + ** Failers +No match + ac +No match + +/^(?=a(*ACCEPT)b)/ + ac + 0: + +/^(?(?!a(*SKIP)b))/ + ac + 0: + /-- End of testinput11 --/ diff --git a/testdata/testoutput7 b/testdata/testoutput7 index c6c9df4..2aab80d 100644 --- a/testdata/testoutput7 +++ b/testdata/testoutput7 @@ -7584,4 +7584,30 @@ No match BAD No match +/^(?!a(*SKIP)b)/ + ac +Error -16 + +/^(?=a(*SKIP)b|ac)/ + ** Failers +No match + ac +Error -16 + +/^(?=a(*THEN)b|ac)/ + ac +Error -16 + +/^(?=a(*PRUNE)b)/ + ab +Error -16 + ** Failers +No match + ac +Error -16 + +/^(?(?!a(*SKIP)b))/ + ac +Error -16 + /-- End of testinput7 --/ |