Revision: 395
http://vcs.pcre.org/viewvc?view=rev&revision=395
Author: ph10
Date: 2009-03-20 11:22:42 +0000 (Fri, 20 Mar 2009)
Log Message:
-----------
Fix looping bug by recognizing that a conditional with only one branch may
match an empty string.
Modified Paths:
--------------
code/trunk/pcre_compile.c
code/trunk/pcre_exec.c
code/trunk/testdata/testinput1
code/trunk/testdata/testoutput1
Modified: code/trunk/pcre_compile.c
===================================================================
--- code/trunk/pcre_compile.c 2009-03-18 16:38:23 UTC (rev 394)
+++ code/trunk/pcre_compile.c 2009-03-20 11:22:42 UTC (rev 395)
@@ -1663,18 +1663,26 @@
{
BOOL empty_branch;
if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
-
- /* Scan a closed bracket */
-
- empty_branch = FALSE;
- do
- {
- if (!empty_branch && could_be_empty_branch(code, endcode, utf8))
- empty_branch = TRUE;
+
+ /* If a conditional group has only one branch, there is a second, implied,
+ empty branch, so just skip over the conditional, because it could be empty.
+ Otherwise, scan the individual branches of the group. */
+
+ if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
code += GET(code, 1);
+ else
+ {
+ empty_branch = FALSE;
+ do
+ {
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf8))
+ empty_branch = TRUE;
+ code += GET(code, 1);
+ }
+ while (*code == OP_ALT);
+ if (!empty_branch) return FALSE; /* All branches are non-empty */
}
- while (*code == OP_ALT);
- if (!empty_branch) return FALSE; /* All branches are non-empty */
+
c = *code;
continue;
}
Modified: code/trunk/pcre_exec.c
===================================================================
--- code/trunk/pcre_exec.c 2009-03-18 16:38:23 UTC (rev 394)
+++ code/trunk/pcre_exec.c 2009-03-20 11:22:42 UTC (rev 395)
@@ -635,7 +635,7 @@
{
minimize = possessive = FALSE;
op = *ecode;
-
+
/* For partial matching, remember if we ever hit the end of the subject after
matching at least one subject character. */
@@ -880,7 +880,7 @@
goto TAIL_RECURSE;
}
}
- else /* Condition false & no 2nd alternative */
+ else /* Condition false & no alternative */
{
ecode += 1 + LINK_SIZE;
}
Modified: code/trunk/testdata/testinput1
===================================================================
--- code/trunk/testdata/testinput1 2009-03-18 16:38:23 UTC (rev 394)
+++ code/trunk/testdata/testinput1 2009-03-20 11:22:42 UTC (rev 395)
@@ -4061,4 +4061,7 @@
/(?(?=.*b).*b|^d)/
abc
+/^%((?(?=[a])[^%])|b)*%$/
+ %ab%
+
/ End of testinput1 /
Modified: code/trunk/testdata/testoutput1
===================================================================
--- code/trunk/testdata/testoutput1 2009-03-18 16:38:23 UTC (rev 394)
+++ code/trunk/testdata/testoutput1 2009-03-20 11:22:42 UTC (rev 395)
@@ -6641,4 +6641,9 @@
abc
0: ab
+/^%((?(?=[a])[^%])|b)*%$/
+ %ab%
+ 0: %ab%
+ 1:
+
/ End of testinput1 /