After fixing the ticket 3787 strchr issue, this patch cleans up other
potentially incorrect uses of strchr for the '\0' case.
In mutt_multi_choice(), mutt_getch() can technically return 0. Although
it seems the user would have to try quite hard to do this, it's
incorrect to return that index into letters. Change "ch.ch==0" to be
considered the same as an abort.
is_email_wsp() is used in a couple places where it wasn't obvious
whether '\0' was being accounted for, so add an explicit check to the
function.
Inside eat_date(), if mutt_extract_token() had no input and returned
"", the strchr ("<>=", buffer.data[0]) below would return a pointer.
In actuality, this is prevented by an empty parameter check inside
mutt_pattern_comp(), but it doesn't hurt to make it the same as
eat_regexp() and have the check explicitly done here too.
rfc2047_encode() was another borderline case for adding a check. The
convert_string() sets a length, so it seems highly unlikely that *t
could be 0, but doesn't hurt to add the check.
The find_encoded_word() fix looks necessary. If the passed in s was
something like "=?charset?" (followed by EOS, '\0'), the strchr("BbQq",
q[1]) would in fact return a pointer and the following q[2] would read
past the end of string. If q[2] happened to be '?', it might even
continue reading in the for loop below.
Lastly, in parse_mailboxdomain(), the potential overread was already
fixed in changeset:
a6919571eb59, but although the nonspecial and special
strchr() line happens to "work" for the case of '\0', it's pretty
fragile to leave as is. It's better to be explicit and just return if
we hit EOS without calling next_token().
{
mutt_refresh ();
ch = mutt_getch ();
- if (ch.ch < 0 || CI_is_return (ch.ch))
+ /* (ch.ch == 0) is technically possible. Treat the same as < 0 (abort) */
+ if (ch.ch <= 0 || CI_is_return (ch.ch))
{
choice = -1;
break;
static inline int is_email_wsp(char c)
{
- return strchr(EMAIL_WSP, c) != NULL;
+ return c && (strchr(EMAIL_WSP, c) != NULL);
}
strfcpy (err->data, _("error in expression"), err->dsize);
return (-1);
}
+ if (!*buffer.data)
+ {
+ snprintf (err->data, err->dsize, _("Empty expression"));
+ return (-1);
+ }
memset (&min, 0, sizeof (min));
/* the `0' time is Jan 1, 1970 UTC, so in order to prevent a negative time
if (!t0) t0 = t;
t1 = t;
}
- else if (specials && strchr (specials, *t))
+ else if (specials && *t && strchr (specials, *t))
{
if (!s0) s0 = t;
s1 = t;
0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:\"/[]?.=", *q);
q++)
;
- if (q[0] != '?' || !strchr ("BbQq", q[1]) || q[2] != '?')
+ if (q[0] != '?' || q[1] == '\0' || !strchr ("BbQq", q[1]) || q[2] != '?')
continue;
/* non-strict check since many MUAs will not encode spaces and question marks */
for (q = q + 3; 0x20 <= *q && *q < 0x7f && (*q != '?' || q[1] != '='); q++)
while (*s)
{
s = skip_email_wsp(s);
+ if (! *s)
+ return s;
+
if (strchr (nonspecial, *s) == NULL && is_special (*s))
return s;