#include "mutt_idna.h"
-const char RFC822Specials[] = "@.,:;<>[]\\\"()";
-
void address_wipe(address_t *addr)
{
p_delete(&addr->personal);
return NULL;
}
-#define is_special(x) strchr(RFC822Specials,x)
+const char RFC822Specials[] = "@.,:;<>[]\\\"()";
static const char *next_phrase(const char *s, static_buf *buf)
{
return parse_quote(s + 1, buf);
}
- if (is_special(*s)) {
+ if (strchr(RFC822Specials, *s)) {
stbuf_append(buf, *s);
return s + 1;
}
while (*s) {
- if (ISSPACE(*s) || is_special(*s))
+ if (ISSPACE(*s) || strchr(RFC822Specials, *s))
break;
stbuf_append(buf, *s++);
}
while (*s) {
s = skipspaces(s);
- if (!strchr(nonspecial, *s) && is_special(*s))
+ if (!strchr(nonspecial, *s) && strchr(RFC822Specials, *s))
return s;
if (*s == '(') {
/* Output functions */
/****************************************************************************/
-void
-rfc822_cat(char *buf, size_t buflen, const char *value, const char *specials)
+ssize_t
+rfc822_strcpy(char *buf, ssize_t buflen, const char *p, const char *specials)
{
- if (strpbrk(value, specials)) {
- char tmp[256], *pc = tmp;
- size_t tmplen = sizeof (tmp) - 3;
-
- *pc++ = '"';
- for (; *value && tmplen > 1; value++) {
- if (*value == '\\' || *value == '"') {
- *pc++ = '\\';
- tmplen--;
+ if (strpbrk(p, specials)) {
+ ssize_t pos = 0;
+
+ buf[pos++] = '"';
+
+ while (*p && pos < buflen - 2) {
+ if (*p == '\\' || *p == '"') {
+ if (pos >= buflen - 4)
+ break;
+ buf[pos++] = '\\';
}
- *pc++ = *value;
- tmplen--;
+
+ buf[pos++] = *p++;
}
- *pc++ = '"';
- *pc = 0;
- m_strcpy(buf, buflen, tmp);
+
+ buf[pos++] = '"';
+ buf[pos] = '\0';
+ return pos;
} else {
- m_strcpy(buf, buflen, value);
+ return m_strcpy(buf, buflen, p);
}
}
-void rfc822_write_address_single(char *buf, size_t buflen, address_t * addr,
- int display)
+ssize_t rfc822_write_address_single(char *buf, ssize_t buflen,
+ address_t *addr, int display)
{
- size_t len;
- char *pbuf = buf;
- char *pc;
+ ssize_t pos = 0;
if (!addr)
- return;
+ return 0;
buflen--; /* save room for the terminal nul */
if (addr->personal) {
- if (strpbrk (addr->personal, RFC822Specials)) {
- if (!buflen)
- goto done;
- *pbuf++ = '"';
- buflen--;
- for (pc = addr->personal; *pc && buflen > 0; pc++) {
- if (*pc == '"' || *pc == '\\') {
- if (!buflen)
- goto done;
- *pbuf++ = '\\';
- buflen--;
- }
- if (!buflen)
- goto done;
- *pbuf++ = *pc;
- buflen--;
- }
- if (!buflen)
- goto done;
- *pbuf++ = '"';
- buflen--;
- }
- else {
- if (!buflen)
- goto done;
- m_strcpy(pbuf, buflen, addr->personal);
- len = m_strlen(pbuf);
- pbuf += len;
- buflen -= len;
- }
-
- if (!buflen)
+ pos = rfc822_strcpy(buf, buflen, addr->personal, RFC822Specials);
+ if (pos + 2 >= buflen)
goto done;
- *pbuf++ = ' ';
- buflen--;
- }
- if (addr->personal || (addr->mailbox && *addr->mailbox == '@')) {
- if (!buflen)
- goto done;
- *pbuf++ = '<';
- buflen--;
+ buf[pos++] = ' ';
+ buf[pos++] = '<';
}
if (addr->mailbox) {
- if (!buflen)
- goto done;
- if (ascii_strcmp (addr->mailbox, "@") && !display) {
- m_strcpy(pbuf, buflen, addr->mailbox);
- len = m_strlen(pbuf);
- }
- else if (ascii_strcmp (addr->mailbox, "@") && display) {
- m_strcpy(pbuf, buflen, mutt_addr_for_display(addr));
- len = m_strlen(pbuf);
- }
- else {
- *pbuf = '\0';
- len = 0;
+ if (!display) {
+ pos += m_strcpy(buf + pos, buflen - pos, addr->mailbox);
+ } else {
+ pos += m_strcpy(buf + pos, buflen - pos, mutt_addr_for_display(addr));
}
- pbuf += len;
- buflen -= len;
- if (addr->personal || (addr->mailbox && *addr->mailbox == '@')) {
- if (!buflen)
+ if (addr->personal) {
+ if (pos + 1 >= buflen)
goto done;
- *pbuf++ = '>';
- buflen--;
+ buf[pos++] = '>';
}
if (addr->group) {
- if (!buflen)
+ if (pos + 1 >= buflen)
goto done;
- *pbuf++ = ':';
- buflen--;
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
+ buf[pos++] = ':';
}
- }
- else {
- if (!buflen)
+ } else {
+ if (pos + 1 >= buflen)
goto done;
- *pbuf++ = ';';
- buflen--;
+ buf[pos++] = ';';
}
-done:
+
+ done:
/* no need to check for length here since we already save space at the
beginning of this routine */
- *pbuf = 0;
+ buf[pos] = 0;
+ return pos;
}
/* note: it is assumed that `buf' is nul terminated! */
-void rfc822_write_address (char *buf, size_t buflen, address_t * addr,
- int display)
+ssize_t
+rfc822_write_address(char *buf, ssize_t buflen, address_t *addr, int display)
{
- char *pbuf = buf;
- size_t len = m_strlen(buf);
+ ssize_t pos;
buflen--; /* save room for the terminal nul */
+ pos = m_strnlen(buf, buflen);
- if (len > 0) {
- if (len > buflen)
- return; /* safety check for bogus arguments */
-
- pbuf += len;
- buflen -= len;
- if (!buflen)
- goto done;
- *pbuf++ = ',';
- buflen--;
- if (!buflen)
+ if (pos) {
+ if (pos + 2 >= buflen)
goto done;
- *pbuf++ = ' ';
- buflen--;
+
+ buf[pos++] = ',';
+ buf[pos++] = ' ';
}
- for (; addr && buflen > 0; addr = addr->next) {
- /* use buflen+1 here because we already saved space for the trailing
- nul char, and the subroutine can make use of it */
- rfc822_write_address_single (pbuf, buflen + 1, addr, display);
-
- /* this should be safe since we always have at least 1 char passed into
- the above call, which means `pbuf' should always be nul terminated */
- len = m_strlen(pbuf);
- pbuf += len;
- buflen -= len;
-
- /* if there is another address, and its not a group mailbox name or
- group terminator, add a comma to separate the addresses */
- if (addr->next && addr->next->mailbox && !addr->group) {
- if (!buflen)
- goto done;
- *pbuf++ = ',';
- buflen--;
- if (!buflen)
- goto done;
- *pbuf++ = ' ';
- buflen--;
+ for (; addr; addr = addr->next) {
+ pos += rfc822_write_address_single(buf + pos, buflen + 1 - pos,
+ addr, display);
+
+ if (!addr->group && addr->next && addr->next->mailbox) {
+ /* if there is another address, and its not a group mailbox name or
+ group terminator, add a comma to separate the addresses */
+ if (pos + 2 >= buflen)
+ break;
+
+ buf[pos++] = ',';
+ buf[pos++] = ' ';
}
}
-done:
- *pbuf = 0;
+
+ done:
+ buf[pos] = '\0';
+ return pos;
}