On Fri, Dec 14, 2012 at 05:37:32PM -0600, David Champion wrote:
diff -r c4c65eadeb71 -r 7a90f541ff69 muttlib.c
--- a/muttlib.c Sat Dec 08 12:31:11 2012 +0100
+++ b/muttlib.c Fri Dec 14 17:28:55 2012 -0600
@@ -1053,6 +1053,100 @@
      *p = '_';
}

+char *mutt_apply_replace (char *dbuf, size_t dlen, char *sbuf, REPLACE_LIST 
*rlist)
+{
+  REPLACE_LIST *l;
+  static regmatch_t *pmatch = NULL;
+  static int nmatch = 0;
+  static char twinbuf[2][LONG_STRING];
+  int switcher = 0;
+  char *p;
+  int i, n;
+  int tlen = 0;
+  char *src, *dst;
+
+  if (dbuf && dlen)
+    dbuf[0] = '\0';
+
+  if (sbuf == NULL || *sbuf == '\0')
+    return dbuf;
+
+  twinbuf[0][0] = '\0';
+  twinbuf[1][0] = '\0';
+  src = twinbuf[switcher];
+  dst = src;
+
+  strncpy(src, sbuf, LONG_STRING-1);
+  src[LONG_STRING-1] = '\0';

I think this first copy is unnecessary. It should be sufficient to have:

src = sbuf;

+
+  for (l = rlist; l; l = l->next)
+  {
+    /* If this pattern needs more matches, expand pmatch. */
+    if (l->nmatch > nmatch)
+    {
+      safe_realloc (&pmatch, l->nmatch * sizeof(regmatch_t));
+      nmatch = l->nmatch;
+    }
+
+    if (regexec (l->rx->rx, src, l->nmatch, pmatch, 0) == 0)
+    {
+      tlen = 0;
+      switcher ^= 1;
+      dst = twinbuf[switcher];
+
+      dprint (5, (debugfile, "mutt_apply_replace: %s matches %s\n", src, 
l->rx->pattern));
+
+      /* Copy into other twinbuf with substitutions */
+      if (l->template)
+      {
+        for (p = l->template; *p; )
+        {
+         if (*p == '%')
+         {
+           p++;
+           if (*p == 'L')
+           {
+             p++;
+             strncpy(&dst[tlen], src, pmatch[0].rm_so);

You need to ensure that tlen < LONG_STRING here since this occurs in the loop over the templates, otherwise there is the potential for overflow.

+             tlen += pmatch[0].rm_so;
+           }
+           else if (*p == 'R')
+           {
+             p++;
+             strncpy(&dst[tlen], &src[pmatch[0].rm_eo], LONG_STRING-tlen-1);

Same here.

+             tlen += strlen(src) - pmatch[0].rm_eo;
+           }
+           else
+           {
+             n = strtoul(p, &p, 10);               /* get subst number */
+             while (isdigit((unsigned char)*p))    /* skip subst token */
+                ++p;

This for loop will always be a noop, because the preceding strtoul() call will set 'p' to point to a non-digit character.

+             for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < 
LONG_STRING-1); i++)
+               dst[tlen++] = src[i];
+           }
+         }
+         else
+           dst[tlen++] = *p++;

Same issue regarding tlen here.

+        }
+      }
+      dst[tlen] = '\0';

And here.

+      dprint (5, (debugfile, "mutt_apply_replace: subst %s\n", dst));
+    }
+    src = dst;
+  }
+
+  if (dbuf)
+  {
+    strncpy(dbuf, dst, dlen-1);
+    dbuf[dlen-1] = '\0';
+  }
+  else
+  {
+    dbuf = strdup(dst);

Should use safe_strdup() here instead.

+  }
+  return dbuf;
+}
+

Reply via email to