Blame SOURCES/pcre-8.32-Fix-compile-time-loop-for-recursive-reference-within.patch

cb67f2
From 58c834052f0985406919de157297e0c340c5b2ed Mon Sep 17 00:00:00 2001
cb67f2
From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
cb67f2
Date: Fri, 8 Aug 2014 15:22:51 +0000
cb67f2
Subject: [PATCH 2/2] Fix compile-time loop for recursive reference within a
cb67f2
 group with an indefinite repeat.
cb67f2
MIME-Version: 1.0
cb67f2
Content-Type: text/plain; charset=UTF-8
cb67f2
Content-Transfer-Encoding: 8bit
cb67f2
cb67f2
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1498 2f5784b3-3f2a-0410-8824-cb99058d5e15
cb67f2
Signed-off-by: Petr Písař <ppisar@redhat.com>
cb67f2
cb67f2
Petr Pisar: Ported to 8.32.
cb67f2
cb67f2
Signed-off-by: Petr Písař <ppisar@redhat.com>
cb67f2
---
cb67f2
 pcre_compile.c       | 17 +++++++----------
cb67f2
 testdata/testinput1  |  6 ++++++
cb67f2
 testdata/testoutput1 | 10 ++++++++++
cb67f2
 3 files changed, 23 insertions(+), 10 deletions(-)
cb67f2
cb67f2
diff --git a/pcre_compile.c b/pcre_compile.c
cb67f2
index ce72527..86cd0c8 100644
cb67f2
--- a/pcre_compile.c
cb67f2
+++ b/pcre_compile.c
cb67f2
@@ -2398,6 +2398,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
cb67f2
   if (c == OP_RECURSE)
cb67f2
     {
cb67f2
     const pcre_uchar *scode = cd->start_code + GET(code, 1);
cb67f2
+    const pcre_uchar *endgroup = scode;
cb67f2
     BOOL empty_branch;
cb67f2
 
cb67f2
     /* Test for forward reference or uncompleted reference. This is disabled
cb67f2
@@ -2412,20 +2413,16 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
cb67f2
       if (GET(scode, 1) == 0) return TRUE;    /* Unclosed */
cb67f2
       }
cb67f2
     
cb67f2
-    /* If we are scanning a completed pattern, there are no forward references 
cb67f2
-    and all groups are complete. We need to detect whether this is a recursive 
cb67f2
-    call, as otherwise there will be an infinite loop. If it is a recursion,
cb67f2
-    just skip over it. Simple recursions are easily detected. For mutual 
cb67f2
-    recursions we keep a chain on the stack. */ 
cb67f2
+    /* If the reference is to a completed group, we need to detect whether this
cb67f2
+    is a recursive call, as otherwise there will be an infinite loop. If it is
cb67f2
+    a recursion, just skip over it. Simple recursions are easily detected. For
cb67f2
+    mutual recursions we keep a chain on the stack. */
cb67f2
      
cb67f2
+    do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
cb67f2
+    if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
cb67f2
     else
cb67f2
       {  
cb67f2
       recurse_check *r = recurses;
cb67f2
-      const pcre_uchar *endgroup = scode;
cb67f2
-       
cb67f2
-      do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
cb67f2
-      if (code >= scode && code <= endgroup) continue;  /* Simple recursion */
cb67f2
-      
cb67f2
       for (r = recurses; r != NULL; r = r->prev)
cb67f2
         if (r->group == scode) break;
cb67f2
       if (r != NULL) continue;   /* Mutual recursion */
cb67f2
diff --git a/testdata/testinput1 b/testdata/testinput1
cb67f2
index 3e1061e..c45e1ba 100644
cb67f2
--- a/testdata/testinput1
cb67f2
+++ b/testdata/testinput1
cb67f2
@@ -4967,6 +4967,12 @@ however, we need the complication for Perl. ---/
cb67f2
 
cb67f2
 /((?(R1)a+|(?1)b))/
cb67f2
     aaaabcde
cb67f2
+    
cb67f2
+/((?(R)a|(?1)))*/
cb67f2
+    aaa
cb67f2
+
cb67f2
+/((?(R)a|(?1)))+/
cb67f2
+    aaa
cb67f2
 
cb67f2
 /a(*:any 
cb67f2
 name)/K
cb67f2
diff --git a/testdata/testoutput1 b/testdata/testoutput1
cb67f2
index 5015448..f0eae49 100644
cb67f2
--- a/testdata/testoutput1
cb67f2
+++ b/testdata/testoutput1
cb67f2
@@ -8271,6 +8271,16 @@ MK: M
cb67f2
     aaaabcde
cb67f2
  0: aaaab
cb67f2
  1: aaaab
cb67f2
+    
cb67f2
+/((?(R)a|(?1)))*/
cb67f2
+    aaa
cb67f2
+ 0: aaa
cb67f2
+ 1: a
cb67f2
+
cb67f2
+/((?(R)a|(?1)))+/
cb67f2
+    aaa
cb67f2
+ 0: aaa
cb67f2
+ 1: a
cb67f2
 
cb67f2
 /a(*:any 
cb67f2
 name)/K
cb67f2
-- 
cb67f2
2.5.5
cb67f2