[Pcre-svn] [1577] code/trunk: Fix infinite recursion in the …

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1577] code/trunk: Fix infinite recursion in the JIT compiler when certain patterns when certain patterns are analysed.
Revision: 1577
          http://vcs.pcre.org/viewvc?view=rev&revision=1577
Author:   zherczeg
Date:     2015-07-20 08:53:12 +0100 (Mon, 20 Jul 2015)
Log Message:
-----------
Fix infinite recursion in the JIT compiler when certain patterns when certain patterns are analysed.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/pcre_jit_compile.c
    code/trunk/testdata/testinput12
    code/trunk/testdata/testoutput12


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2015-07-17 15:15:18 UTC (rev 1576)
+++ code/trunk/ChangeLog    2015-07-20 07:53:12 UTC (rev 1577)
@@ -81,7 +81,10 @@
 20. A possessively repeated conditional group that could match an empty string,
     for example, /(?(R))*+/, was incorrectly compiled.


+21. Fix infinite recursion in the JIT compiler when certain patterns such as
+    /(?:|a|){100}x/ are analysed.


+
Version 8.37 28-April-2015
--------------------------


Modified: code/trunk/pcre_jit_compile.c
===================================================================
--- code/trunk/pcre_jit_compile.c    2015-07-17 15:15:18 UTC (rev 1576)
+++ code/trunk/pcre_jit_compile.c    2015-07-20 07:53:12 UTC (rev 1577)
@@ -3214,7 +3214,7 @@
 bytes[0] = len;
 }


-static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
+static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count)
 {
 /* Recursive function, which scans prefix literals. */
 BOOL last, any, caseless;
@@ -3232,9 +3232,14 @@
 repeat = 1;
 while (TRUE)
   {
+  if (*rec_count == 0)
+    return 0;
+  rec_count--;
+
   last = TRUE;
   any = FALSE;
   caseless = FALSE;
+
   switch (*cc)
     {
     case OP_CHARI:
@@ -3296,7 +3301,7 @@
 #ifdef SUPPORT_UTF
     if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
 #endif
-    max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
+    max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
     if (max_chars == 0)
       return consumed;
     last = FALSE;
@@ -3319,7 +3324,7 @@
     alternative = cc + GET(cc, 1);
     while (*alternative == OP_ALT)
       {
-      max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
+      max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
       if (max_chars == 0)
         return consumed;
       alternative += GET(alternative, 1);
@@ -3561,6 +3566,7 @@
 int range_right = -1, range_len = 3 - 1;
 sljit_ub *update_table = NULL;
 BOOL in_range;
+pcre_uint32 rec_count;


for (i = 0; i < MAX_N_CHARS; i++)
{
@@ -3569,7 +3575,8 @@
bytes[i * MAX_N_BYTES] = 0;
}

-max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
+rec_count = 10000;
+max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);

if (max <= 1)
return FALSE;

Modified: code/trunk/testdata/testinput12
===================================================================
--- code/trunk/testdata/testinput12    2015-07-17 15:15:18 UTC (rev 1576)
+++ code/trunk/testdata/testinput12    2015-07-20 07:53:12 UTC (rev 1577)
@@ -97,4 +97,6 @@


/(a(?:a|b|c|d|e)b){8,16}/S++

+/(?:|a|){100}x/S++
+
/-- End of testinput12 --/

Modified: code/trunk/testdata/testoutput12
===================================================================
--- code/trunk/testdata/testoutput12    2015-07-17 15:15:18 UTC (rev 1576)
+++ code/trunk/testdata/testoutput12    2015-07-20 07:53:12 UTC (rev 1577)
@@ -193,4 +193,6 @@


/(a(?:a|b|c|d|e)b){8,16}/S++

+/(?:|a|){100}x/S++
+
/-- End of testinput12 --/