diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2009-03-20 11:22:42 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2009-03-20 11:22:42 +0000 |
commit | 180f0ae93baecec24df25f671865f1238b9563cd (patch) | |
tree | 41d222f9207d4d7577f2dda9fa83f6d728e3d719 | |
parent | 42895029897bc56f99d0d9acd546a98c45961a5a (diff) | |
download | pcre-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.c | 28 | ||||
-rw-r--r-- | pcre_exec.c | 4 | ||||
-rw-r--r-- | testdata/testinput1 | 3 | ||||
-rw-r--r-- | testdata/testoutput1 | 5 |
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 / |