[Pcre-svn] [1498] code/trunk: Fix compile-time loop for recu…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1498] code/trunk: Fix compile-time loop for recursive reference within a group with an indefinite
Revision: 1498
          http://vcs.pcre.org/viewvc?view=rev&revision=1498
Author:   ph10
Date:     2014-08-08 16:22:51 +0100 (Fri, 08 Aug 2014)


Log Message:
-----------
Fix compile-time loop for recursive reference within a group with an indefinite
repeat.

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/pcre_compile.c
    code/trunk/testdata/testinput1
    code/trunk/testdata/testoutput1


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2014-08-08 14:50:26 UTC (rev 1497)
+++ code/trunk/ChangeLog    2014-08-08 15:22:51 UTC (rev 1498)
@@ -89,6 +89,11 @@
     back reference was optional (had quantifier with a minimum of zero). This
     example compiled incorrect code: /(((a\2)|(a*)\g<-1>))*/ and other examples 
     caused segmentation faults because of stack overflows at compile time. 
+    
+20. A pattern such as /((?(R)a|(?1)))+/, which contains a recursion within a 
+    group that is quantified with an indefinite repeat, caused a compile-time
+    loop which used up all the system stack and provoked a segmentation fault.
+    This was not the same bug as 19 above.



Version 8.35 04-April-2014

Modified: code/trunk/pcre_compile.c
===================================================================
--- code/trunk/pcre_compile.c    2014-08-08 14:50:26 UTC (rev 1497)
+++ code/trunk/pcre_compile.c    2014-08-08 15:22:51 UTC (rev 1498)
@@ -2374,6 +2374,7 @@
   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 @@
       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. */


Modified: code/trunk/testdata/testinput1
===================================================================
--- code/trunk/testdata/testinput1    2014-08-08 14:50:26 UTC (rev 1497)
+++ code/trunk/testdata/testinput1    2014-08-08 15:22:51 UTC (rev 1498)
@@ -4937,7 +4937,13 @@


 /((?(R1)a+|(?1)b))/
     aaaabcde
+    
+/((?(R)a|(?1)))*/
+    aaa


+/((?(R)a|(?1)))+/
+    aaa
+
 /a(*:any 
 name)/K
     abc


Modified: code/trunk/testdata/testoutput1
===================================================================
--- code/trunk/testdata/testoutput1    2014-08-08 14:50:26 UTC (rev 1497)
+++ code/trunk/testdata/testoutput1    2014-08-08 15:22:51 UTC (rev 1498)
@@ -8234,7 +8234,17 @@
     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
     abc