[Pcre-svn] [1535] code/trunk: Add recursion depth limit to a…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1535] code/trunk: Add recursion depth limit to auto-possessification.
Revision: 1535
          http://vcs.pcre.org/viewvc?view=rev&revision=1535
Author:   ph10
Date:     2015-03-25 16:51:51 +0000 (Wed, 25 Mar 2015)


Log Message:
-----------
Add recursion depth limit to auto-possessification.

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    2015-03-24 10:33:21 UTC (rev 1534)
+++ code/trunk/ChangeLog    2015-03-25 16:51:51 UTC (rev 1535)
@@ -110,6 +110,11 @@
     when this assertion was used as a condition, for example (?(?!)a|b). In
     pcre2_match() it worked by luck; in pcre2_dfa_match() it gave an incorrect
     error about an unsupported item.
+    
+29. For some types of pattern, for example /Z*(|d*){216}/, the auto-
+    possessification code could take exponential time to complete. A recursion 
+    depth limit of 1000 has been imposed to limit the resources used by this 
+    optimization.



Version 8.36 26-September-2014

Modified: code/trunk/pcre_compile.c
===================================================================
--- code/trunk/pcre_compile.c    2015-03-24 10:33:21 UTC (rev 1534)
+++ code/trunk/pcre_compile.c    2015-03-25 16:51:51 UTC (rev 1535)
@@ -3093,7 +3093,7 @@


static BOOL
compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
- const pcre_uint32 *base_list, const pcre_uchar *base_end)
+ const pcre_uint32 *base_list, const pcre_uchar *base_end, int *rec_limit)
{
pcre_uchar c;
pcre_uint32 list[8];
@@ -3110,6 +3110,9 @@
BOOL accepted, invert_bits;
BOOL entered_a_group = FALSE;

+if (*rec_limit == 0) return FALSE;
+--(*rec_limit);
+
/* Note: the base_list[1] contains whether the current opcode has greedy
(represented by a non-zero value) quantifier. This is a different from
other character type lists, which stores here that the character iterator
@@ -3180,7 +3183,8 @@

     while (*next_code == OP_ALT)
       {
-      if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE;
+      if (!compare_opcodes(code, utf, cd, base_list, base_end, rec_limit))
+        return FALSE;
       code = next_code + 1 + LINK_SIZE;
       next_code += GET(next_code, 1);
       }
@@ -3200,7 +3204,7 @@
     /* The bracket content will be checked by the
     OP_BRA/OP_CBRA case above. */
     next_code += 1 + LINK_SIZE;
-    if (!compare_opcodes(next_code, utf, cd, base_list, base_end))
+    if (!compare_opcodes(next_code, utf, cd, base_list, base_end, rec_limit))
       return FALSE;


     code += PRIV(OP_lengths)[c];
@@ -3633,6 +3637,7 @@
 const pcre_uchar *end;
 pcre_uchar *repeat_opcode;
 pcre_uint32 list[8];
+int rec_limit;


 for (;;)
   {
@@ -3653,7 +3658,8 @@
       get_chr_property_list(code, utf, cd->fcc, list) : NULL;
     list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;


-    if (end != NULL && compare_opcodes(end, utf, cd, list, end))
+    rec_limit = 10000;
+    if (end != NULL && compare_opcodes(end, utf, cd, list, end, &rec_limit))
       {
       switch(c)
         {
@@ -3709,7 +3715,8 @@


       list[1] = (c & 1) == 0;


-      if (compare_opcodes(end, utf, cd, list, end))
+      rec_limit = 10000;
+      if (compare_opcodes(end, utf, cd, list, end, &rec_limit))
         {
         switch (c)
           {


Modified: code/trunk/testdata/testinput1
===================================================================
--- code/trunk/testdata/testinput1    2015-03-24 10:33:21 UTC (rev 1534)
+++ code/trunk/testdata/testinput1    2015-03-25 16:51:51 UTC (rev 1535)
@@ -5725,4 +5725,6 @@


/(\2)(\1)/

+"Z*(|d*){216}"
+
/-- End of testinput1 --/

Modified: code/trunk/testdata/testoutput1
===================================================================
--- code/trunk/testdata/testoutput1    2015-03-24 10:33:21 UTC (rev 1534)
+++ code/trunk/testdata/testoutput1    2015-03-25 16:51:51 UTC (rev 1535)
@@ -9422,4 +9422,6 @@


/(\2)(\1)/

+"Z*(|d*){216}"
+
/-- End of testinput1 --/