diff options
author | Kevin McCarthy <kevin@8t8.us> | 2021-07-16 14:00:01 -0700 |
---|---|---|
committer | Kevin McCarthy <kevin@8t8.us> | 2021-07-17 15:14:59 -0700 |
commit | df727efb43e751b9d089784c9c55fb6a083b25e2 (patch) | |
tree | c01a4e4e9a5dad01b5f7791bca75d569335abb64 | |
parent | f80f3ea117a54cdf15d6a380c5106b2a2a09437e (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.c | 74 |
1 files changed, 32 insertions, 42 deletions
@@ -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; } |