summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2021-07-16 14:00:01 -0700
committerKevin McCarthy <kevin@8t8.us>2021-07-17 15:14:59 -0700
commitdf727efb43e751b9d089784c9c55fb6a083b25e2 (patch)
treec01a4e4e9a5dad01b5f7791bca75d569335abb64
parentf80f3ea117a54cdf15d6a380c5106b2a2a09437e (diff)
Rewrite mutt_apply_replace() to use buffers.
This removes the size truncation limit. It also removes a compiler warning about strncpy truncation.
-rw-r--r--muttlib.c74
1 files changed, 32 insertions, 42 deletions
diff --git a/muttlib.c b/muttlib.c
index faf1b2b8..9efe164c 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -1415,32 +1415,25 @@ const char *mutt_getcwd (BUFFER *cwd)
return retval;
}
-/* Note this function uses a fixed size buffer of LONG_STRING and so
- * should only be used for visual modifications, such as disp_subj. */
-char *mutt_apply_replace (char *dbuf, size_t dlen, char *sbuf, REPLACE_LIST *rlist)
+char *mutt_apply_replace (char *d, size_t dlen, char *s, REPLACE_LIST *rlist)
{
REPLACE_LIST *l;
static regmatch_t *pmatch = NULL;
static int nmatch = 0;
- static char twinbuf[2][LONG_STRING];
- int switcher = 0;
+ BUFFER *srcbuf, *destbuf;
char *p;
- int i, n;
- size_t cpysize, tlen;
- char *src, *dst;
+ unsigned int n;
- if (dbuf && dlen)
- dbuf[0] = '\0';
+ if (d && dlen)
+ d[0] = '\0';
- if (sbuf == NULL || *sbuf == '\0' || (dbuf && !dlen))
- return dbuf;
+ if (s == NULL || *s == '\0' || (d && !dlen))
+ return d;
- twinbuf[0][0] = '\0';
- twinbuf[1][0] = '\0';
- src = twinbuf[switcher];
- dst = src;
+ srcbuf = mutt_buffer_pool_get ();
+ destbuf = mutt_buffer_pool_get ();
- strfcpy(src, sbuf, LONG_STRING);
+ mutt_buffer_strcpy (srcbuf, s);
for (l = rlist; l; l = l->next)
{
@@ -1451,18 +1444,15 @@ char *mutt_apply_replace (char *dbuf, size_t dlen, char *sbuf, REPLACE_LIST *rli
nmatch = l->nmatch;
}
- if (regexec (l->rx->rx, src, l->nmatch, pmatch, 0) == 0)
+ if (regexec (l->rx->rx, mutt_b2s (srcbuf), l->nmatch, pmatch, 0) == 0)
{
- tlen = 0;
- switcher ^= 1;
- dst = twinbuf[switcher];
+ dprint (5, (debugfile, "mutt_apply_replace: %s matches %s\n",
+ mutt_b2s (srcbuf), l->rx->pattern));
- dprint (5, (debugfile, "mutt_apply_replace: %s matches %s\n", src, l->rx->pattern));
-
- /* Copy into other twinbuf with substitutions */
+ mutt_buffer_clear (destbuf);
if (l->template)
{
- for (p = l->template; *p && (tlen < LONG_STRING - 1); )
+ for (p = l->template; *p; )
{
if (*p == '%')
{
@@ -1470,41 +1460,41 @@ char *mutt_apply_replace (char *dbuf, size_t dlen, char *sbuf, REPLACE_LIST *rli
if (*p == 'L')
{
p++;
- cpysize = MIN (pmatch[0].rm_so, LONG_STRING - tlen - 1);
- strncpy(&dst[tlen], src, cpysize);
- tlen += cpysize;
+ mutt_buffer_addstr_n (destbuf, mutt_b2s (srcbuf), pmatch[0].rm_so);
}
else if (*p == 'R')
{
p++;
- cpysize = MIN (strlen (src) - pmatch[0].rm_eo, LONG_STRING - tlen - 1);
- strncpy(&dst[tlen], &src[pmatch[0].rm_eo], cpysize);
- tlen += cpysize;
+ mutt_buffer_addstr (destbuf, srcbuf->data + pmatch[0].rm_eo);
}
else
{
- n = strtoul(p, &p, 10); /* get subst number */
+ if (!mutt_atoui (p, &n, MUTT_ATOI_ALLOW_TRAILING) && (n < l->nmatch))
+ mutt_buffer_addstr_n (destbuf, srcbuf->data + pmatch[n].rm_so,
+ pmatch[n].rm_eo - pmatch[n].rm_so);
while (isdigit((unsigned char)*p)) /* skip subst token */
++p;
- for (i = pmatch[n].rm_so; (i < pmatch[n].rm_eo) && (tlen < LONG_STRING-1); i++)
- dst[tlen++] = src[i];
}
}
else
- dst[tlen++] = *p++;
+ mutt_buffer_addch (destbuf, *p++);
}
}
- dst[tlen] = '\0';
- dprint (5, (debugfile, "mutt_apply_replace: subst %s\n", dst));
+
+ mutt_buffer_strcpy (srcbuf, mutt_b2s (destbuf));
+ dprint (5, (debugfile, "mutt_apply_replace: subst %s\n", mutt_b2s (destbuf)));
}
- src = dst;
}
- if (dbuf)
- strfcpy(dbuf, dst, dlen);
+ if (d)
+ strfcpy (d, mutt_b2s (srcbuf), dlen);
else
- dbuf = safe_strdup(dst);
- return dbuf;
+ d = safe_strdup (mutt_b2s (srcbuf));
+
+ mutt_buffer_pool_release (&srcbuf);
+ mutt_buffer_pool_release (&destbuf);
+
+ return d;
}