]> granicus.if.org Git - mutt/commitdiff
Fix possible unintentional '\0' strchr matches.
authorKevin McCarthy <kevin@8t8.us>
Mon, 9 Nov 2015 23:40:42 +0000 (15:40 -0800)
committerKevin McCarthy <kevin@8t8.us>
Mon, 9 Nov 2015 23:40:42 +0000 (15:40 -0800)
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().

curs_lib.c
lib.h
pattern.c
rfc2047.c
rfc822.c

index d70c327f8d2170b33b5c29d3da57df98a8da3fad..e28d88c0f4d7075e6e62ed57befe87888dd63948 100644 (file)
@@ -713,7 +713,8 @@ int mutt_multi_choice (char *prompt, char *letters)
   {
     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;
diff --git a/lib.h b/lib.h
index 3c385873345b6eccadc63fe020b95df62223be78..0b7a85b467bf3e1d761466b0b36dc83811f89535 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -112,7 +112,7 @@ static inline char *skip_email_wsp(const char *s)
 
 static inline int is_email_wsp(char c)
 {
-  return strchr(EMAIL_WSP, c) != NULL;
+  return c && (strchr(EMAIL_WSP, c) != NULL);
 }
 
 
index 7af1c3811e09d76eb1fe03155b53a48c760dd789..6f05b4a50b68aaa8e3b7455b81d0e421c9cb8f48 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -582,6 +582,11 @@ static int eat_date (pattern_t *pat, BUFFER *s, BUFFER *err)
     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
index b5e8704d1f2ad24a6860c3c3cd60b58ae2180696..a1a6c2e4a5fd7f5c21bc0529d45a72fd0f32f2df 100644 (file)
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -438,7 +438,7 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col,
       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;
@@ -740,7 +740,7 @@ static const char *find_encoded_word (const char *s, const char **x)
         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++)
index 803478247d2a7efcbf1253aab9703f09c891584a..d9aad9e9c8e3da84dc31d8ad5042e0db468f6bdb 100644 (file)
--- a/rfc822.c
+++ b/rfc822.c
@@ -229,6 +229,9 @@ parse_mailboxdomain (const char *s, const char *nonspecial,
   while (*s)
   {
     s = skip_email_wsp(s);
+    if (! *s)
+      return s;
+
     if (strchr (nonspecial, *s) == NULL && is_special (*s))
       return s;