summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2010-01-02 12:40:07 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2010-01-02 12:40:07 +0000
commit1d5dad0b7e2087e3667cbb402e74636970cea259 (patch)
treecc237e32be27ed3608f6de72a86aba82e1e7d4db
parentd70bdebcc62f48ae54bb2d7e7216d629bdc5dfcc (diff)
downloadpcre-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--ChangeLog23
-rw-r--r--pcre_dfa_exec.c6
-rw-r--r--pcre_exec.c11
-rw-r--r--testdata/testinput1121
-rw-r--r--testdata/testinput718
-rw-r--r--testdata/testoutput1130
-rw-r--r--testdata/testoutput726
7 files changed, 125 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index d7adfca..fb86a98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 --/