Revision: 473
http://vcs.pcre.org/viewvc?view=rev&revision=473
Author: ph10
Date: 2010-01-02 12:40:07 +0000 (Sat, 02 Jan 2010)
Log Message:
-----------
Fix bugs relating to the use of (*SKIP) etc in assertions.
Modified Paths:
--------------
code/trunk/ChangeLog
code/trunk/pcre_dfa_exec.c
code/trunk/pcre_exec.c
code/trunk/testdata/testinput11
code/trunk/testdata/testinput7
code/trunk/testdata/testoutput11
code/trunk/testdata/testoutput7
Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/ChangeLog 2010-01-02 12:40:07 UTC (rev 473)
@@ -5,18 +5,29 @@
----------------------
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
----------------------
Modified: code/trunk/pcre_dfa_exec.c
===================================================================
--- code/trunk/pcre_dfa_exec.c 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/pcre_dfa_exec.c 2010-01-02 12:40:07 UTC (rev 473)
@@ -7,7 +7,7 @@
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 @@
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 @@
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); }
Modified: code/trunk/pcre_exec.c
===================================================================
--- code/trunk/pcre_exec.c 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/pcre_exec.c 2010-01-02 12:40:07 UTC (rev 473)
@@ -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 @@
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 @@
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);
}
Modified: code/trunk/testdata/testinput11
===================================================================
--- code/trunk/testdata/testinput11 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/testdata/testinput11 2010-01-02 12:40:07 UTC (rev 473)
@@ -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 --/
Modified: code/trunk/testdata/testinput7
===================================================================
--- code/trunk/testdata/testinput7 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/testdata/testinput7 2010-01-02 12:40:07 UTC (rev 473)
@@ -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 --/
Modified: code/trunk/testdata/testoutput11
===================================================================
--- code/trunk/testdata/testoutput11 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/testdata/testoutput11 2010-01-02 12:40:07 UTC (rev 473)
@@ -712,4 +712,34 @@
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 --/
Modified: code/trunk/testdata/testoutput7
===================================================================
--- code/trunk/testdata/testoutput7 2009-12-11 16:42:50 UTC (rev 472)
+++ code/trunk/testdata/testoutput7 2010-01-02 12:40:07 UTC (rev 473)
@@ -7584,4 +7584,30 @@
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 --/