[Pcre-svn] [876] code/trunk: Fix oss-fuzz bugs 3852 and 3891…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [876] code/trunk: Fix oss-fuzz bugs 3852 and 3891 (same bug); mis-closing external captures by
Revision: 876
          http://www.exim.org/viewvc/pcre2?view=rev&revision=876
Author:   ph10
Date:     2017-10-29 16:58:38 +0000 (Sun, 29 Oct 2017)
Log Message:
-----------
Fix oss-fuzz bugs 3852 and 3891 (same bug); mis-closing external captures by 
*ACCEPT inside assertions.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/src/pcre2_compile.c
    code/trunk/src/pcre2_internal.h
    code/trunk/src/pcre2_intmodedep.h
    code/trunk/testdata/testinput1
    code/trunk/testdata/testoutput1


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/ChangeLog    2017-10-29 16:58:38 UTC (rev 876)
@@ -39,7 +39,13 @@
 path names to 512 characters. There is now a check on the absolute length of
 full path file names, which may be up to 2047 characters long.


+12. When an assertion contained (*ACCEPT) it caused all open capturing groups
+to be closed (as for a non-assertion ACCEPT), which was wrong and could lead to
+misbehaviour for subsequent references to groups that started outside the
+recursion. ACCEPT in an assertion now closes only those groups that were
+started within that assertion. Fixes oss-fuzz issues 3852 and 3891.

+
Version 10.30 14-August-2017
----------------------------


Modified: code/trunk/src/pcre2_compile.c
===================================================================
--- code/trunk/src/pcre2_compile.c    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/src/pcre2_compile.c    2017-10-29 16:58:38 UTC (rev 876)
@@ -2194,7 +2194,7 @@
 {
 uint32_t *previous_callout = *pcalloutptr;


-if (previous_callout != NULL) previous_callout[2] = (uint32_t)(ptr -
+if (previous_callout != NULL) previous_callout[2] = (uint32_t)(ptr -
cb->start_pattern - (PCRE2_SIZE)previous_callout[1]);

 if (!auto_callout) previous_callout = NULL; else
@@ -5599,14 +5599,17 @@
     /* ===================================================================*/
     /* Deal with (*VERB)s. */


-    /* Check for open captures before ACCEPT and convert it to ASSERT_ACCEPT if
-    in an assertion. In the first pass, just accumulate the length required;
+    /* Check for open captures before ACCEPT and close those that are within
+    the same assertion level, also converting ACCEPT to ASSERT_ACCEPT in an
+    assertion. In the first pass, just accumulate the length required;
     otherwise hitting (*ACCEPT) inside many nested parentheses can cause
     workspace overflow. Do not set firstcu after *ACCEPT. */


     case META_ACCEPT:
     cb->had_accept = TRUE;
-    for (oc = cb->open_caps; oc != NULL; oc = oc->next)
+    for (oc = cb->open_caps;
+         oc != NULL && oc->assert_depth >= cb->assert_depth;
+         oc = oc->next)
       {
       if (lengthptr != NULL)
         {
@@ -7483,6 +7486,7 @@
   capitem.number = capnumber;
   capitem.next = cb->open_caps;
   capitem.flag = FALSE;
+  capitem.assert_depth = cb->assert_depth;
   cb->open_caps = &capitem;
   }



Modified: code/trunk/src/pcre2_internal.h
===================================================================
--- code/trunk/src/pcre2_internal.h    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/src/pcre2_internal.h    2017-10-29 16:58:38 UTC (rev 876)
@@ -1770,6 +1770,7 @@
   struct open_capitem *next;    /* Chain link */
   uint16_t number;              /* Capture number */
   uint16_t flag;                /* Set TRUE if recursive back ref */
+  uint16_t assert_depth;        /* Assertion depth when opened */ 
 } open_capitem;


/* Layout of the UCP type table that translates property names into types and

Modified: code/trunk/src/pcre2_intmodedep.h
===================================================================
--- code/trunk/src/pcre2_intmodedep.h    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/src/pcre2_intmodedep.h    2017-10-29 16:58:38 UTC (rev 876)
@@ -723,6 +723,8 @@
   PCRE2_SIZE erroroffset;          /* Offset of error in pattern */
   uint16_t names_found;            /* Number of entries so far */
   uint16_t name_entry_size;        /* Size of each entry */
+  uint16_t parens_depth;           /* Depth of nested parentheses */
+  uint16_t assert_depth;           /* Depth of nested assertions */
   open_capitem *open_caps;         /* Chain of open capture items */
   named_group *named_groups;       /* Points to vector in pre-compile */
   uint32_t named_group_list_size;  /* Number of entries in the list */
@@ -741,8 +743,6 @@
   uint32_t class_range_end;        /* Overall class range end */
   PCRE2_UCHAR nl[4];               /* Newline string when fixed length */
   int  max_lookbehind;             /* Maximum lookbehind (characters) */
-  int  parens_depth;               /* Depth of nested parentheses */
-  int  assert_depth;               /* Depth of nested assertions */
   int  req_varyopt;                /* "After variable item" flag for reqbyte */
   BOOL had_accept;                 /* (*ACCEPT) encountered */
   BOOL had_pruneorskip;            /* (*PRUNE) or (*SKIP) encountered */


Modified: code/trunk/testdata/testinput1
===================================================================
--- code/trunk/testdata/testinput1    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/testdata/testinput1    2017-10-29 16:58:38 UTC (rev 876)
@@ -6149,4 +6149,14 @@
 /[[:digit:]-]+/
     12-24


+/((?<=((*ACCEPT)) )\1?\b) /
+\= Expect no match     
+    ((?<=((*ACCEPT)) )\\1?\\b)\x20
+
+/((?<=((*ACCEPT))X)\1?Y)\1/
+    XYYZ
+
+/((?<=((*ACCEPT))X)\1?Y(*ACCEPT))\1/
+    XYYZ
+
 # End of testinput1 


Modified: code/trunk/testdata/testoutput1
===================================================================
--- code/trunk/testdata/testoutput1    2017-10-23 16:57:22 UTC (rev 875)
+++ code/trunk/testdata/testoutput1    2017-10-29 16:58:38 UTC (rev 876)
@@ -9741,4 +9741,21 @@
     12-24
  0: 12-24


+/((?<=((*ACCEPT)) )\1?\b) /
+\= Expect no match     
+    ((?<=((*ACCEPT)) )\\1?\\b)\x20
+No match
+
+/((?<=((*ACCEPT))X)\1?Y)\1/
+    XYYZ
+ 0: YY
+ 1: Y
+ 2: 
+
+/((?<=((*ACCEPT))X)\1?Y(*ACCEPT))\1/
+    XYYZ
+ 0: Y
+ 1: Y
+ 2: 
+
 # End of testinput1