summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2009-03-20 11:22:42 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2009-03-20 11:22:42 +0000
commit180f0ae93baecec24df25f671865f1238b9563cd (patch)
tree41d222f9207d4d7577f2dda9fa83f6d728e3d719
parent42895029897bc56f99d0d9acd546a98c45961a5a (diff)
downloadpcre-180f0ae93baecec24df25f671865f1238b9563cd.tar.gz
Fix looping bug by recognizing that a conditional with only one branch may
match an empty string. git-svn-id: svn://vcs.exim.org/pcre/code/trunk@395 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--pcre_compile.c28
-rw-r--r--pcre_exec.c4
-rw-r--r--testdata/testinput13
-rw-r--r--testdata/testoutput15
4 files changed, 28 insertions, 12 deletions
diff --git a/pcre_compile.c b/pcre_compile.c
index cfd803d..bac03da 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -1663,18 +1663,26 @@ for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE
{
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;
}
diff --git a/pcre_exec.c b/pcre_exec.c
index 21cc990..afdd88f 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -635,7 +635,7 @@ for (;;)
{
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 @@ for (;;)
goto TAIL_RECURSE;
}
}
- else /* Condition false & no 2nd alternative */
+ else /* Condition false & no alternative */
{
ecode += 1 + LINK_SIZE;
}
diff --git a/testdata/testinput1 b/testdata/testinput1
index ecfd365..8b0caa4 100644
--- a/testdata/testinput1
+++ b/testdata/testinput1
@@ -4061,4 +4061,7 @@
/(?(?=.*b).*b|^d)/
abc
+/^%((?(?=[a])[^%])|b)*%$/
+ %ab%
+
/ End of testinput1 /
diff --git a/testdata/testoutput1 b/testdata/testoutput1
index 83ef39c..81b0cb8 100644
--- a/testdata/testoutput1
+++ b/testdata/testoutput1
@@ -6641,4 +6641,9 @@ No match
abc
0: ab
+/^%((?(?=[a])[^%])|b)*%$/
+ %ab%
+ 0: %ab%
+ 1:
+
/ End of testinput1 /