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;
+}
+