add new inline funtion skip_email_wsp() to be used in lieu of SKIPWS() when parsing ASCII protocols rather than user input.
change use of SKIPWS() to skip_email_wsp() in places where it is likely to be a problem.
{
char path[_POSIX_PATH_MAX]; /* tempfile used to edit headers + body */
char buffer[LONG_STRING];
- char *p;
+ const char *p;
FILE *ifp, *ofp;
int i, keep;
ENVELOPE *n;
if (fcc && ascii_strncasecmp ("fcc:", cur->data, 4) == 0)
{
- p = cur->data + 4;
- SKIPWS (p);
+ p = skip_email_wsp(cur->data + 4);
if (*p)
{
strfcpy (fcc, p, fcclen);
{
BODY *body;
BODY *parts;
- int l = 0;
+ size_t l = 0;
- p = cur->data + 7;
- SKIPWS (p);
+ p = skip_email_wsp(cur->data + 7);
if (*p)
{
for ( ; *p && *p != ' ' && *p != '\t'; p++)
if (l < sizeof (path) - 1)
path[l++] = *p;
}
- if (*p)
- *p++ = 0;
- SKIPWS (p);
+ p = skip_email_wsp(p);
path[l] = 0;
mutt_expand_path (path, sizeof (path));
on some systems */
# define SKIPWS(c) while (*(c) && isspace ((unsigned char) *(c))) c++;
+#define EMAIL_WSP " \t\r\n"
+
+/* skip over WSP as defined by RFC5322. This is used primarily for parsing
+ * header fields. */
+
+static inline char *skip_email_wsp(const char *s)
+{
+ if (s)
+ return (char *)(s + strspn(s, EMAIL_WSP));
+ return (char *)s;
+}
+
+static inline int is_email_wsp(char c)
+{
+ return strchr(EMAIL_WSP, c) != NULL;
+}
+
+
/*
* These functions aren't defined in lib.c, but
* they are used there.
int mutt_signed_handler (BODY *, STATE *);
-int mutt_parse_crypt_hdr (char *, int, int);
+int mutt_parse_crypt_hdr (const char *, int, int);
void convert_to_7bit (BODY *);
if (*p != ';')
{
i = p - s;
-
- new = mutt_new_parameter ();
-
- new->attribute = safe_malloc (i + 1);
- memcpy (new->attribute, s, i);
- new->attribute[i] = 0;
-
/* remove whitespace from the end of the attribute name */
- while (ISSPACE (new->attribute[--i]))
- new->attribute[i] = 0;
+ while (i > 0 && is_email_wsp(s[i-1]))
+ --i;
+
+ /* the check for the missing parameter token is here so that we can skip
+ * over any quoted value that may be present.
+ */
+ if (i == 0)
+ {
+ dprint(1, (debugfile, "parse_parameters: missing attribute: %s\n", s));
+ new = NULL;
+ }
+ else
+ {
+ new = mutt_new_parameter ();
+ new->attribute = mutt_substrdup(s, s + i);
+ }
- s = p + 1; /* skip over the = */
- SKIPWS (s);
+ s = skip_email_wsp(p + 1); /* skip over the = */
if (*s == '"')
{
buffer[i] = 0;
}
- new->value = safe_strdup (buffer);
-
- dprint (2, (debugfile, "parse_parameter: `%s' = `%s'\n",
- new->attribute ? new->attribute : "",
- new->value ? new->value : ""));
-
- /* Add this parameter to the list */
- if (head)
+ /* if the attribute token was missing, 'new' will be NULL */
+ if (new)
{
- cur->next = new;
- cur = cur->next;
+ new->value = safe_strdup (buffer);
+
+ dprint (2, (debugfile, "parse_parameter: `%s' = `%s'\n",
+ new->attribute ? new->attribute : "",
+ new->value ? new->value : ""));
+
+ /* Add this parameter to the list */
+ if (head)
+ {
+ cur->next = new;
+ cur = cur->next;
+ }
+ else
+ head = cur = new;
}
- else
- head = cur = new;
}
else
{
/* Find the next parameter */
if (*s != ';' && (s = strchr (s, ';')) == NULL)
- break; /* no more parameters */
+ break; /* no more parameters */
do
{
- s++;
-
- /* Move past any leading whitespace */
- SKIPWS (s);
+ /* Move past any leading whitespace. the +1 skips over the semicolon */
+ s = skip_email_wsp(s + 1);
}
while (*s == ';'); /* skip empty parameters */
}
- bail:
+bail:
rfc2231_decode_parameters (&head);
return (head);
}
-static void parse_content_disposition (char *s, BODY *ct)
+static void parse_content_disposition (const char *s, BODY *ct)
{
PARAMETER *parms;
/* Check to see if a default filename was given */
if ((s = strchr (s, ';')) != NULL)
{
- s++;
- SKIPWS (s);
+ s = skip_email_wsp(s + 1);
if ((s = mutt_get_parameter ("filename", (parms = parse_parameters (s)))))
mutt_str_replace (&ct->filename, s);
if ((s = mutt_get_parameter ("name", parms)))
if ((c = strchr (line, ':')))
{
*c = 0;
- c++;
- SKIPWS (c);
+ c = skip_email_wsp(c + 1);
if (!*c)
{
dprint (1, (debugfile, "mutt_read_mime_header(): skipping empty header field: %s\n", line));
if (*tz != '(')
return tz; /* no need to do anything */
- tz++;
- SKIPWS (tz);
+ tz = skip_email_wsp(tz + 1);
if ((p = strpbrk (tz, " )")) == NULL)
return tz;
len = p - tz;
t++;
else
t = scratch;
- SKIPWS (t);
+ t = skip_email_wsp(t);
memset (&tm, 0, sizeof (tm));
}
*p = 0;
- p++;
- SKIPWS (p);
+ p = skip_email_wsp(p + 1);
if (!*p)
continue; /* skip empty header fields */
if (!mutt_strncmp (msg, "-ERR ", 5))
{
- c2 = msg + 5;
- SKIPWS (c2);
+ c2 = skip_email_wsp(msg + 5);
if (*c2)
c = c2;
if (!ascii_strncasecmp (line, "SASL", 4))
{
FREE (&pop_data->auth_list);
- c = line + 4;
- SKIPWS (c);
+ c = skip_email_wsp(line + 4);
pop_data->auth_list = safe_strdup (c);
}
LIST *tmp;
LIST *last = NULL;
LIST *next;
- char *p;
+ const char *p;
int opt_delete;
if (!Postponed)
{
/* if a mailbox is currently open, look to see if the orignal message
the user attempted to reply to is in this mailbox */
- p = tmp->data + 18;
- SKIPWS (p);
+ p = skip_email_wsp(tmp->data + 18);
if (!ctx->id_hash)
ctx->id_hash = mutt_make_id_hash (ctx);
*cur = hash_find (ctx->id_hash, p);
}
else if (ascii_strncasecmp ("X-Mutt-Fcc:", tmp->data, 11) == 0)
{
- p = tmp->data + 11;
- SKIPWS (p);
+ p = skip_email_wsp(tmp->data + 11);
strfcpy (fcc, p, fcclen);
mutt_pretty_mailbox (fcc, fcclen);
-int mutt_parse_crypt_hdr (char *p, int set_signas, int crypt_app)
+int mutt_parse_crypt_hdr (const char *p, int set_signas, int crypt_app)
{
char smime_cryptalg[LONG_STRING] = "\0";
char sign_as[LONG_STRING] = "\0", *q;
if (!WithCrypto)
return 0;
- SKIPWS (p);
+ p = skip_email_wsp(p);
for (; *p; p++)
{
}
else
{
- *ch++ = 0;
- SKIPWS (ch);
+ *ch = 0;
+ ch = skip_email_wsp(ch + 1);
break;
}
}
#else
#define safe_strdup strdup
#define safe_malloc malloc
-#define SKIPWS(x) while(iswsp(*x))x++
#define FREE(x) safe_free(x)
#define strfcpy(a,b,c) {if (c) {strncpy(a,b,c);a[c-1]=0;}}
#define LONG_STRING 1024
#define terminate_buffer(a, b) terminate_string(a, b, sizeof (a) - 1)
-/* undefine the version defined in lib.h */
-#undef SKIPWS
-
-/* uses the iswsp() function defined in this module so we get RFC5322 semantics */
-#define SKIPWS(s) while(iswsp(*s)) s++
-
const char RFC822Specials[] = "@.,:;<>[]\\\"()";
#define is_special(x) strchr(RFC822Specials,x)
"bad address spec"
};
-/* iswsp
- *
- * Returns non-zero if 'c' is a whitespace character as defined by RFC5322.
- *
- * WSP is defined as ASCII space (32) or hard tab (9).
- */
-static inline int iswsp(char c)
-{
- return (c == ' ' || c == '\t');
-}
-
void rfc822_dequote_comment (char *s)
{
char *w = s;
}
while (*s)
{
- if (iswsp(*s) || is_special (*s))
+ if (is_email_wsp(*s) || is_special (*s))
break;
if (*tokenlen < tokenmax)
token[(*tokenlen)++] = *s;
while (*s)
{
- SKIPWS (s);
+ s = skip_email_wsp(s);
if (strchr (nonspecial, *s) == NULL && is_special (*s))
return s;
char token[LONG_STRING];
size_t tokenlen = 0;
- SKIPWS (s);
+ s = skip_email_wsp(s);
/* find the end of the route */
if (*s == '@')
ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
{
int ws_pending, nl;
+#ifdef EXACT_ADDRESS
const char *begin, *ps;
+#endif
+ const char *ps;
char comment[LONG_STRING], phrase[LONG_STRING];
size_t phraselen = 0, commentlen = 0;
ADDRESS *cur, *last = NULL;
while (last && last->next)
last = last->next;
- ws_pending = iswsp (*s);
+ ws_pending = is_email_wsp (*s);
if ((nl = mutt_strlen (s)))
nl = s[nl - 1] == '\n';
- SKIPWS (s);
+ s = skip_email_wsp(s);
+#ifdef EXACT_ADDRESS
begin = s;
+#endif
while (*s)
{
if (*s == ',')
commentlen = 0;
phraselen = 0;
s++;
- begin = s;
- SKIPWS (begin);
+#ifdef EXACT_ADDRESS
+ begin = skip_email_wsp(s);
+#endif
}
else if (*s == '(')
{
phraselen = 0;
commentlen = 0;
s++;
- begin = s;
- SKIPWS (begin);
+#ifdef EXACT_ADDRESS
+ begin = skip_email_wsp(s);
+#endif
}
else if (*s == ';')
{
phraselen = 0;
commentlen = 0;
s++;
- begin = s;
- SKIPWS (begin);
+#ifdef EXACT_ADDRESS
+ begin = skip_email_wsp(s);
+#endif
}
else if (*s == '<')
{
}
s = ps;
}
- ws_pending = iswsp (*s);
- SKIPWS (s);
+ ws_pending = is_email_wsp(*s);
+ s = skip_email_wsp(s);
}
if (phraselen)
}
else
{
- char *p;
+ const char *p;
buf[0] = 0;
for (; uh; uh = uh->next)
{
if (ascii_strncasecmp ("subject:", uh->data, 8) == 0)
{
- p = uh->data + 8;
- SKIPWS (p);
+ p = skip_email_wsp(uh->data + 8);
strncpy (buf, p, sizeof (buf));
}
}
else
{
tagbuf = mutt_substrdup (start, t);
- ++t; /* skip over the colon separating the header field name and value */
-
- /* skip over any leading whitespace (WSP, as defined in RFC5322) */
- while (*t == ' ' || *t == '\t')
- t++;
-
+ /* skip over the colon separating the header field name and value */
+ t = skip_email_wsp(t + 1);
valbuf = mutt_substrdup (t, end);
}
dprint(4,(debugfile,"mwoh: buf[%s%s] too long, "
*p = '\0';
- p++; SKIPWS (p);
+ p = skip_email_wsp(p + 1);
if (!*p)
{
*q = ':';
continue;
i = p - h->data;
- ++p; SKIPWS (p);
+ p = skip_email_wsp(p + 1);
tmp = safe_strdup (p);
if (!tmp)
safe_asprintf (&scratch, "%s: %s", tag, value);
scratch[taglen] = 0; /* overwrite the colon as mutt_parse_rfc822_line expects */
- value = &scratch[taglen + 1];
- SKIPWS (value);
+ value = skip_email_wsp(&scratch[taglen + 1]);
mutt_parse_rfc822_line (e, NULL, scratch, value, 1, 0, 0, &last);
FREE (&scratch);
}