101 lines
3.1 KiB
Diff
101 lines
3.1 KiB
Diff
From fd411b0b71fc1d0bd1977d0a86e5711599f875d8 Mon Sep 17 00:00:00 2001
|
|
From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
|
|
Date: Fri, 8 Aug 2014 15:22:51 +0000
|
|
Subject: [PATCH] Fix compile-time loop for recursive reference within a group
|
|
with an indefinite repeat.
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1498 2f5784b3-3f2a-0410-8824-cb99058d5e15
|
|
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
|
Petr Pisar: Ported to 8.35.
|
|
|
|
diff --git a/pcre_compile.c b/pcre_compile.c
|
|
index 8276d0f..4bb05b9 100644
|
|
--- a/pcre_compile.c
|
|
+++ b/pcre_compile.c
|
|
@@ -2374,6 +2374,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
|
|
if (c == OP_RECURSE)
|
|
{
|
|
const pcre_uchar *scode = cd->start_code + GET(code, 1);
|
|
+ const pcre_uchar *endgroup = scode;
|
|
BOOL empty_branch;
|
|
|
|
/* Test for forward reference or uncompleted reference. This is disabled
|
|
@@ -2388,24 +2389,20 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
|
|
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
|
|
}
|
|
|
|
- /* If we are scanning a completed pattern, there are no forward references
|
|
- and all groups are complete. We need to detect whether this is a recursive
|
|
- call, as otherwise there will be an infinite loop. If it is a recursion,
|
|
- just skip over it. Simple recursions are easily detected. For mutual
|
|
- recursions we keep a chain on the stack. */
|
|
+ /* If the reference is to a completed group, we need to detect whether this
|
|
+ is a recursive call, as otherwise there will be an infinite loop. If it is
|
|
+ a recursion, just skip over it. Simple recursions are easily detected. For
|
|
+ mutual recursions we keep a chain on the stack. */
|
|
|
|
+ do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
|
|
+ if (code >= scode && code <= endgroup) continue; /* Simple recursion */
|
|
else
|
|
- {
|
|
+ {
|
|
recurse_check *r = recurses;
|
|
- const pcre_uchar *endgroup = scode;
|
|
-
|
|
- do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
|
|
- if (code >= scode && code <= endgroup) continue; /* Simple recursion */
|
|
-
|
|
for (r = recurses; r != NULL; r = r->prev)
|
|
if (r->group == scode) break;
|
|
if (r != NULL) continue; /* Mutual recursion */
|
|
- }
|
|
+ }
|
|
|
|
/* Completed reference; scan the referenced group, remembering it on the
|
|
stack chain to detect mutual recursions. */
|
|
diff --git a/testdata/testinput1 b/testdata/testinput1
|
|
index 6fd62ba..123e3d3 100644
|
|
--- a/testdata/testinput1
|
|
+++ b/testdata/testinput1
|
|
@@ -4937,6 +4937,12 @@ however, we need the complication for Perl. ---/
|
|
|
|
/((?(R1)a+|(?1)b))/
|
|
aaaabcde
|
|
+
|
|
+/((?(R)a|(?1)))*/
|
|
+ aaa
|
|
+
|
|
+/((?(R)a|(?1)))+/
|
|
+ aaa
|
|
|
|
/a(*:any
|
|
name)/K
|
|
diff --git a/testdata/testoutput1 b/testdata/testoutput1
|
|
index eeddf0f..5e71900 100644
|
|
--- a/testdata/testoutput1
|
|
+++ b/testdata/testoutput1
|
|
@@ -8234,6 +8234,16 @@ MK: M
|
|
aaaabcde
|
|
0: aaaab
|
|
1: aaaab
|
|
+
|
|
+/((?(R)a|(?1)))*/
|
|
+ aaa
|
|
+ 0: aaa
|
|
+ 1: a
|
|
+
|
|
+/((?(R)a|(?1)))+/
|
|
+ aaa
|
|
+ 0: aaa
|
|
+ 1: a
|
|
|
|
/a(*:any
|
|
name)/K
|
|
--
|
|
1.9.3
|
|
|