Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37518243
en ru br
ALT Linux repos
S:8.45-alt2
5.0: 7.8-alt2
4.1: 7.6-alt1.M41.1
4.0: 7.6-alt1.M40.1
+updates:7.4-alt1
3.0: 6.4-alt1

Group :: System/Libraries
RPM: pcre

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch
Download


From b3f0b0dd971314df8f865e221aa1a88e75d6d1a6 Mon Sep 17 00:00:00 2001
From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
Date: Wed, 5 Aug 2015 15:38:32 +0000
Subject: [PATCH] Fix buffer overflow for named references in (?| situations.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported for 8.37:
commit 7af8e8717def179fd7b69e173abd347c1a3547cb
Author: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
Date:   Wed Aug 5 15:38:32 2015 +0000
    Fix buffer overflow for named references in (?| situations.
    git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1585 2f5784b3-3f2a-0410-8824-cb99058d5e15
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
 pcre_compile.c       | 74 ++++++++++++++++++++++++++++++----------------------
 pcre_internal.h      |  1 +
 testdata/testinput2  |  2 ++
 testdata/testoutput2 |  2 ++
 4 files changed, 48 insertions(+), 31 deletions(-)
diff --git a/pcre_compile.c b/pcre_compile.c
index f5d2384..5fe5c1d 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -6641,6 +6641,7 @@ for (;; ptr++)
         /* ------------------------------------------------------------ */
         case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */
         reset_bracount = TRUE;
+        cd->dupgroups = TRUE;     /* Record (?| encountered */ 
         /* Fall through */
 
         /* ------------------------------------------------------------ */
@@ -7151,7 +7152,8 @@ for (;; ptr++)
         if (lengthptr != NULL)
           {
           named_group *ng;
-
+          recno = 0;
+           
           if (namelen == 0)
             {
             *errorcodeptr = ERR62;
@@ -7168,32 +7170,6 @@ for (;; ptr++)
             goto FAILED;
             }
 
-          /* The name table does not exist in the first pass; instead we must
-          scan the list of names encountered so far in order to get the
-          number. If the name is not found, set the value to 0 for a forward
-          reference. */
-
-          recno = 0;
-          ng = cd->named_groups;
-          for (i = 0; i < cd->names_found; i++, ng++)
-            {
-            if (namelen == ng->length &&
-                STRNCMP_UC_UC(name, ng->name, namelen) == 0)
-              {
-              open_capitem *oc;
-              recno = ng->number;
-              if (is_recurse) break;
-              for (oc = cd->open_caps; oc != NULL; oc = oc->next)
-                {
-                if (oc->number == recno)
-                  {
-                  oc->flag = TRUE;
-                  break;
-                  }
-                }
-              }
-            }
-
           /* Count named back references. */
 
           if (!is_recurse) cd->namedrefcount++;
@@ -7215,7 +7191,44 @@ for (;; ptr++)
           issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
           only mode, we finesse the bug by allowing more memory always. */
 
-          /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE;
+          *lengthptr += 2 + 2*LINK_SIZE;
+          
+          /* It is even worse than that. The current reference may be to an
+          existing named group with a different number (so apparently not
+          recursive) but which later on is also attached to a group with the
+          current number. This can only happen if $(| has been previous 
+          encountered. In that case, we allow yet more memory, just in case. 
+          (Again, this is fixed "properly" in PCRE2. */
+          
+          if (cd->dupgroups) *lengthptr += 2 + 2*LINK_SIZE;
+
+          /* Otherwise, check for recursion here. The name table does not exist
+          in the first pass; instead we must scan the list of names encountered
+          so far in order to get the number. If the name is not found, leave
+          the value of recno as 0 for a forward reference. */
+           
+          else
+            { 
+            ng = cd->named_groups;
+            for (i = 0; i < cd->names_found; i++, ng++)
+              {
+              if (namelen == ng->length &&
+                  STRNCMP_UC_UC(name, ng->name, namelen) == 0)
+                {
+                open_capitem *oc;
+                recno = ng->number;
+                if (is_recurse) break;
+                for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+                  {
+                  if (oc->number == recno)
+                    {
+                    oc->flag = TRUE;
+                    break;
+                    }
+                  }
+                }
+              }
+            }   
           }
 
         /* In the real compile, search the name table. We check the name
@@ -7262,8 +7275,6 @@ for (;; ptr++)
           for (i++; i < cd->names_found; i++)
             {
             if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
-
-
             count++;
             cslot += cd->name_entry_size;
             }
@@ -9189,6 +9200,7 @@ cd->names_found = 0;
 cd->name_entry_size = 0;
 cd->name_table = NULL;
 cd->dupnames = FALSE;
+cd->dupgroups = FALSE;
 cd->namedrefcount = 0;
 cd->start_code = cworkspace;
 cd->hwm = cworkspace;
@@ -9223,7 +9235,7 @@ if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
 
 DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
   (int)(cd->hwm - cworkspace)));
-
+  
 if (length > MAX_PATTERN_SIZE)
   {
   errorcode = ERR20;
diff --git a/pcre_internal.h b/pcre_internal.h
index dd0ac7f..7ca6020 100644
--- a/pcre_internal.h
+++ b/pcre_internal.h
@@ -2446,6 +2446,7 @@ typedef struct compile_data {
   BOOL had_pruneorskip;             /* (*PRUNE) or (*SKIP) encountered */
   BOOL check_lookbehind;            /* Lookbehinds need later checking */
   BOOL dupnames;                    /* Duplicate names exist */
+  BOOL dupgroups;                   /* Duplicate groups exist: (?| found */ 
   BOOL iscondassert;                /* Next assert is a condition */
   int  nltype;                      /* Newline type */
   int  nllen;                       /* Newline string length */
diff --git a/testdata/testinput2 b/testdata/testinput2
index e12de3a..8e044f8 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -4158,4 +4158,6 @@ backtracking verbs. --/
 
 "(?J:(?|(?'R')(\k'R')|((?'R'))))"
 
+/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
+
 /-- End of testinput2 --/
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index 5bad26c..6019425 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -14430,4 +14430,6 @@ Failed: unmatched parentheses at offset 23
 
 "(?J:(?|(?'R')(\k'R')|((?'R'))))"
 
+/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
+
 /-- End of testinput2 --/
-- 
2.4.3
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin