[Pcre-svn] [238] code/trunk: Fix diagnosis of negative relat…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [238] code/trunk: Fix diagnosis of negative relative references to non-existent groups.
Revision: 238
          http://www.exim.org/viewvc/pcre2?view=rev&revision=238
Author:   ph10
Date:     2015-03-31 16:01:25 +0100 (Tue, 31 Mar 2015)


Log Message:
-----------
Fix diagnosis of negative relative references to non-existent groups.

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 17:34:04 UTC (rev 237)
+++ code/trunk/ChangeLog    2015-03-31 15:01:25 UTC (rev 238)
@@ -55,7 +55,11 @@
 incorrectly compiled and could trigger buffer overflow. This bug was discovered 
 by the LLVM fuzzer.


+14. Negative relative recursive references such as (?-7) to non-existent
+subpatterns were not being diagnosed and could lead to unpredictable behaviour.
+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 17:34:04 UTC (rev 237)
+++ code/trunk/src/pcre2_compile.c    2015-03-31 15:01:25 UTC (rev 238)
@@ -3179,15 +3179,15 @@
   BOOL xclass_has_prop;
 #endif
   int newoptions;
-  uint32_t recno;
-  int refsign;
+  int recno;                               /* Must be signed */
+  int refsign;                             /* Must be signed */
   int skipbytes;
-  uint32_t subreqcu, subfirstcu;
-  int32_t subreqcuflags, subfirstcuflags;
   int terminator;
   unsigned int mclength;
   unsigned int tempbracount;
   uint32_t ec;
+  uint32_t subreqcu, subfirstcu;
+  int32_t subreqcuflags, subfirstcuflags;  /* Must be signed */
   PCRE2_UCHAR mcbuffer[8];


   /* Get next character in the pattern */
@@ -5443,13 +5443,13 @@
             }
           if (refsign != 0) recno = (refsign == CHAR_MINUS)?
             cb->bracount - recno + 1 : recno + cb->bracount;
-          if (recno <= 0 || recno > cb->final_bracount)
+          if (recno <= 0 || (uint32_t)recno > cb->final_bracount)
             {
             *errorcodeptr = ERR15;
             goto FAILED;
             }
           PUT2(code, 2+LINK_SIZE, recno);
-          if (recno > cb->top_backref) cb->top_backref = recno;
+          if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
           break;
           }


@@ -5475,7 +5475,7 @@
           for (;;)
             {
             recno = GET2(slot, 0);   /* Number for last found */
-            if (recno > cb->top_backref) cb->top_backref = recno;
+            if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;
             count++;
             if (++i >= cb->names_found) break;
             slot += cb->name_entry_size;
@@ -6000,7 +6000,7 @@
               open_capitem *oc;
               recno = GET2(slot, 0);
               cb->backref_map |= (recno < 32)? (1 << recno) : 1;
-              if (recno > cb->top_backref) cb->top_backref = recno;
+              if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;


               /* Check to see if this back reference is recursive, that it, it
               is inside the group that it references. A flag is set so that the
@@ -6121,7 +6121,7 @@


             if (called == NULL)
               {
-              if (recno > cb->final_bracount)
+              if ((uint32_t)recno > cb->final_bracount)
                 {
                 *errorcodeptr = ERR15;
                 goto FAILED;
@@ -6626,7 +6626,7 @@
         *code++ = ((options & PCRE2_CASELESS) != 0)? OP_REFI : OP_REF;
         PUT2INC(code, 0, recno);
         cb->backref_map |= (recno < 32)? (1 << recno) : 1;
-        if (recno > cb->top_backref) cb->top_backref = recno;
+        if ((uint32_t)recno > cb->top_backref) cb->top_backref = recno;


         /* Check to see if this back reference is recursive, that it, it
         is inside the group that it references. A flag is set so that the


Modified: code/trunk/testdata/testinput2
===================================================================
--- code/trunk/testdata/testinput2    2015-03-29 17:34:04 UTC (rev 237)
+++ code/trunk/testdata/testinput2    2015-03-31 15:01:25 UTC (rev 238)
@@ -4249,4 +4249,8 @@


"X((?2)()*+){2}"B

+/(?<=\bABQ(3(?-7)))/
+
+/(?<=\bABQ(3(?+7)))/
+
# End of testinput2

Modified: code/trunk/testdata/testoutput2
===================================================================
--- code/trunk/testdata/testoutput2    2015-03-29 17:34:04 UTC (rev 237)
+++ code/trunk/testdata/testoutput2    2015-03-31 15:01:25 UTC (rev 238)
@@ -14251,4 +14251,10 @@
         End
 ------------------------------------------------------------------


+/(?<=\bABQ(3(?-7)))/
+Failed: error 115 at offset 15: reference to non-existent subpattern
+
+/(?<=\bABQ(3(?+7)))/
+Failed: error 115 at offset 15: reference to non-existent subpattern
+
# End of testinput2