summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2009-03-21 12:34:15 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2009-03-21 12:34:15 +0000
commit9582580e18ca51f492526e73c3fb8a485461f379 (patch)
tree0540e1ecd4ab2dbf4c8261e1c4c855d1401123da
parentf93cab0ea13076c269826c5be1e35b1cb678880f (diff)
downloadpcre-9582580e18ca51f492526e73c3fb8a485461f379.tar.gz
Further fix to auto-callout with conditional groups whose condition is an
assertion. git-svn-id: svn://vcs.exim.org/pcre/code/trunk@399 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--ChangeLog5
-rw-r--r--pcre_exec.c14
-rw-r--r--testdata/testinput26
-rw-r--r--testdata/testoutput235
4 files changed, 54 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index e8dbc85..2ba0cbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -42,8 +42,9 @@ Version 7.9 xx-xxx-09
correctly handled. The rule now is that both the assertion and what follows
in the first alternative must satisfy the test.
-9. If auto-callout was enabled in a pattern with a conditional group, PCRE
- could crash during matching, both with pcre_exec() and pcre_dfa_exec().
+9. If auto-callout was enabled in a pattern with a conditional group whose
+ condition was an assertion, PCRE could crash during matching, both with
+ pcre_exec() and pcre_dfa_exec().
10. The PCRE_DOLLAR_ENDONLY option was not working when pcre_dfa_exec() was
used for matching.
diff --git a/pcre_exec.c b/pcre_exec.c
index afdd88f..4681e92 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -561,6 +561,8 @@ int oclength;
uschar occhars[8];
#endif
+int codelink;
+int condcode;
int ctype;
int length;
int max;
@@ -787,6 +789,8 @@ for (;;)
case OP_COND:
case OP_SCOND:
+ codelink= GET(ecode, 1);
+
/* Because of the way auto-callout works during compile, a callout item is
inserted between OP_COND and an assertion condition. */
@@ -813,9 +817,11 @@ for (;;)
ecode += _pcre_OP_lengths[OP_CALLOUT];
}
+ condcode = ecode[LINK_SIZE+1];
+
/* Now see what the actual condition is */
- if (ecode[LINK_SIZE+1] == OP_RREF) /* Recursion test */
+ if (condcode == OP_RREF) /* Recursion test */
{
offset = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
condition = md->recursive != NULL &&
@@ -823,14 +829,14 @@ for (;;)
ecode += condition? 3 : GET(ecode, 1);
}
- else if (ecode[LINK_SIZE+1] == OP_CREF) /* Group used test */
+ else if (condcode == OP_CREF) /* Group used test */
{
offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
condition = offset < offset_top && md->offset_vector[offset] >= 0;
ecode += condition? 3 : GET(ecode, 1);
}
- else if (ecode[LINK_SIZE+1] == OP_DEF) /* DEFINE - always false */
+ else if (condcode == OP_DEF) /* DEFINE - always false */
{
condition = FALSE;
ecode += GET(ecode, 1);
@@ -857,7 +863,7 @@ for (;;)
else
{
condition = FALSE;
- ecode += GET(ecode, 1);
+ ecode += codelink;
}
}
diff --git a/testdata/testinput2 b/testdata/testinput2
index e84a49d..78bda86 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -2749,4 +2749,10 @@ a random value. /Ix
abcxypqr
abcxypqr\Y
+/^"((?(?=[a])[^"])|b)*"$/C
+ "ab"
+
+/^"((?(?=[a])[^"])|b)*"$/
+ "ab"
+
/ End of testinput2 /
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index ddde568..0aaa856 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -9653,6 +9653,8 @@ No need char
+7 ^ ^ b
+7 ^^ b
+7 ^ b
++12 ^ )
++13 ^
0:
abc
--->abc
@@ -9751,4 +9753,37 @@ No match
+0 ^ x
No match
+/^"((?(?=[a])[^"])|b)*"$/C
+ "ab"
+--->"ab"
+ +0 ^ ^
+ +1 ^ "
+ +2 ^^ ((?(?=[a])[^"])|b)*
+ +3 ^^ (?(?=[a])[^"])
+ +5 ^^ (?=[a])
+ +8 ^^ [a]
++11 ^ ^ )
++12 ^^ [^"]
++16 ^ ^ )
++17 ^ ^ |
+ +3 ^ ^ (?(?=[a])[^"])
+ +5 ^ ^ (?=[a])
+ +8 ^ ^ [a]
++21 ^ ^ "
++18 ^ ^ b
++19 ^ ^ )
+ +3 ^ ^ (?(?=[a])[^"])
+ +5 ^ ^ (?=[a])
+ +8 ^ ^ [a]
++21 ^ ^ "
++22 ^ ^ $
++23 ^ ^
+ 0: "ab"
+ 1:
+
+/^"((?(?=[a])[^"])|b)*"$/
+ "ab"
+ 0: "ab"
+ 1:
+
/ End of testinput2 /