[Pcre-svn] [237] code/trunk: Fix bad compile for possessive …

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [237] code/trunk: Fix bad compile for possessive quantifier on group containing a subroutine
Revision: 237
          http://www.exim.org/viewvc/pcre2?view=rev&revision=237
Author:   ph10
Date:     2015-03-29 18:34:04 +0100 (Sun, 29 Mar 2015)


Log Message:
-----------
Fix bad compile for possessive quantifier on group containing a subroutine
reference.

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/src/pcre2_compile.c
    code/trunk/testdata/testinput2
    code/trunk/testdata/testoutput2


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2015-03-29 15:40:45 UTC (rev 236)
+++ code/trunk/ChangeLog    2015-03-29 17:34:04 UTC (rev 237)
@@ -50,7 +50,12 @@
 for the ! or = that would indicate a lookbehind assertion. This bug was
 discovered by the LLVM fuzzer.


+13. A pattern such as /X((?2)()*+){2}+/ which has a possessive quantifier with
+a fixed maximum following a group that contains a subroutine reference was
+incorrectly compiled and could trigger buffer overflow. This bug was discovered
+by the LLVM fuzzer.

+
Version 10.10 06-March-2015
---------------------------


Modified: code/trunk/src/pcre2_compile.c
===================================================================
--- code/trunk/src/pcre2_compile.c    2015-03-29 15:40:45 UTC (rev 236)
+++ code/trunk/src/pcre2_compile.c    2015-03-29 17:34:04 UTC (rev 237)
@@ -1331,7 +1331,7 @@
       empty_branch = FALSE;
       do
         {
-        if (!empty_branch && could_be_empty_branch(code, endcode, utf, cb, 
+        if (!empty_branch && could_be_empty_branch(code, endcode, utf, cb,
           recurses)) empty_branch = TRUE;
         code += GET(code, 1);
         }
@@ -4520,6 +4520,7 @@
       {
       register int i;
       int len = (int)(code - previous);
+      size_t base_hwm_offset = save_hwm_offset;
       PCRE2_UCHAR *bralink = NULL;
       PCRE2_UCHAR *brazeroptr = NULL;


@@ -4668,20 +4669,20 @@

               while (cb->hwm > cb->start_workspace + cb->workspace_size -
                      WORK_SIZE_SAFETY_MARGIN -
-                     (this_hwm_offset - save_hwm_offset))
+                     (this_hwm_offset - base_hwm_offset))
                 {
                 *errorcodeptr = expand_workspace(cb);
                 if (*errorcodeptr != 0) goto FAILED;
                 }


-              for (hc = (PCRE2_UCHAR *)cb->start_workspace + save_hwm_offset;
+              for (hc = (PCRE2_UCHAR *)cb->start_workspace + base_hwm_offset;
                    hc < (PCRE2_UCHAR *)cb->start_workspace + this_hwm_offset;
                    hc += LINK_SIZE)
                 {
                 PUT(cb->hwm, 0, GET(hc, 0) + len);
                 cb->hwm += LINK_SIZE;
                 }
-              save_hwm_offset = this_hwm_offset;
+              base_hwm_offset = this_hwm_offset;
               code += len;
               }
             }
@@ -4749,20 +4750,20 @@


           while (cb->hwm > cb->start_workspace + cb->workspace_size -
                  WORK_SIZE_SAFETY_MARGIN -
-                 (this_hwm_offset - save_hwm_offset))
+                 (this_hwm_offset - base_hwm_offset))
             {
             *errorcodeptr = expand_workspace(cb);
             if (*errorcodeptr != 0) goto FAILED;
             }


-          for (hc = (PCRE2_UCHAR *)cb->start_workspace + save_hwm_offset;
+          for (hc = (PCRE2_UCHAR *)cb->start_workspace + base_hwm_offset;
                hc < (PCRE2_UCHAR *)cb->start_workspace + this_hwm_offset;
                hc += LINK_SIZE)
             {
             PUT(cb->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
             cb->hwm += LINK_SIZE;
             }
-          save_hwm_offset = this_hwm_offset;
+          base_hwm_offset = this_hwm_offset;
           code += len;
           }


@@ -5029,9 +5030,9 @@

     /* First deal with comments. Putting this code right at the start ensures
     that comments have no bad side effects. */
-    
+
     if (ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
-      {   
+      {
       ptr += 2;
       while (ptr < cb->end_pattern && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
       if (*ptr != CHAR_RIGHT_PARENTHESIS)
@@ -5163,7 +5164,7 @@
       *errorcodeptr = ERR60;          /* Verb not recognized */
       goto FAILED;
       }
-      
+
     /* Initialization for "real" parentheses */


     newoptions = options;
@@ -5274,7 +5275,7 @@
                tempptr[2] == CHAR_EXCLAMATION_MARK ||
                  (tempptr[2] == CHAR_LESS_THAN_SIGN &&
                    (tempptr[3] == CHAR_EQUALS_SIGN ||
-                    tempptr[3] == CHAR_EXCLAMATION_MARK))))  
+                    tempptr[3] == CHAR_EXCLAMATION_MARK))))
           {
           cb->iscondassert = TRUE;
           break;


Modified: code/trunk/testdata/testinput2
===================================================================
--- code/trunk/testdata/testinput2    2015-03-29 15:40:45 UTC (rev 236)
+++ code/trunk/testdata/testinput2    2015-03-29 17:34:04 UTC (rev 237)
@@ -4245,4 +4245,8 @@


"(?(?<E>.*!.*)?)"

+"X((?2)()*+){2}+"B
+
+"X((?2)()*+){2}"B
+
# End of testinput2

Modified: code/trunk/testdata/testoutput2
===================================================================
--- code/trunk/testdata/testoutput2    2015-03-29 15:40:45 UTC (rev 236)
+++ code/trunk/testdata/testoutput2    2015-03-29 17:34:04 UTC (rev 237)
@@ -14209,4 +14209,46 @@
 "(?(?<E>.*!.*)?)"
 Failed: error 128 at offset 3: assertion expected after (?( or (?(?C)


+"X((?2)()*+){2}+"B
+------------------------------------------------------------------
+        Bra
+        X
+        Once
+        CBra 1
+        Recurse
+        Braposzero
+        SCBraPos 2
+        KetRpos
+        Ket
+        CBra 1
+        Recurse
+        Braposzero
+        SCBraPos 2
+        KetRpos
+        Ket
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
+"X((?2)()*+){2}"B
+------------------------------------------------------------------
+        Bra
+        X
+        CBra 1
+        Recurse
+        Braposzero
+        SCBraPos 2
+        KetRpos
+        Ket
+        CBra 1
+        Recurse
+        Braposzero
+        SCBraPos 2
+        KetRpos
+        Ket
+        Ket
+        End
+------------------------------------------------------------------
+
 # End of testinput2