]> granicus.if.org Git - neomutt/commitdiff
- my_mbtowcs didn't recover from bad multibyte sequences
authorThomas Roessler <roessler@does-not-exist.org>
Thu, 7 Dec 2006 11:34:34 +0000 (11:34 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Thu, 7 Dec 2006 11:34:34 +0000 (11:34 +0000)
- mutt_format_string was called under the assumption that this
  function can operate in-place. Unfortunately, that assumption
  only holds if replacement_char() returns a one-byte character.

commands.c
curs_lib.c
enter.c
menu.c

index 8ec7c107e0bde3a1fc448d0bf22a3e7082333c09..6f99cbc93f52e74cb6d0369d4250ec921d157248 100644 (file)
@@ -237,6 +237,7 @@ int mutt_display_message (HEADER *cur)
 void ci_bounce_message (HEADER *h, int *redraw)
 {
   char prompt[SHORT_STRING];
+  char scratch[SHORT_STRING];
   char buf[HUGE_STRING] = { 0 };
   ADDRESS *adr = NULL;
   char *err = NULL;
@@ -278,18 +279,18 @@ void ci_bounce_message (HEADER *h, int *redraw)
   rfc822_write_address (buf, sizeof (buf), adr, 1);
 
 #define extra_space (15 + 7 + 2)
-  snprintf (prompt, sizeof (prompt),
+  snprintf (scratch, sizeof (scratch),
            (h ? _("Bounce message to %s") : _("Bounce messages to %s")), buf);
 
   if (mutt_strwidth (prompt) > COLS - extra_space)
   {
     mutt_format_string (prompt, sizeof (prompt),
                        0, COLS-extra_space, 0, 0,
-                       prompt, sizeof (prompt), 0);
+                       scratch, sizeof (scratch), 0);
     safe_strcat (prompt, sizeof (prompt), "...?");
   }
   else
-    safe_strcat (prompt, sizeof (prompt), "?");
+    snprintf (prompt, sizeof (prompt), "%s?", scratch);
 
   if (query_quadoption (OPT_BOUNCE, prompt) != M_YES)
   {
index 169168ea3be9fcc26289af87fb0bbf170cc54b6c..57bf7808034c311865765fe4c930928a080e1b15 100644 (file)
@@ -281,14 +281,15 @@ void mutt_query_exit (void)
 void mutt_curses_error (const char *fmt, ...)
 {
   va_list ap;
+  char scratch[LONG_STRING];
 
   va_start (ap, fmt);
-  vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
+  vsnprintf (scratch, sizeof (scratch), fmt, ap);
   va_end (ap);
   
-  dprint (1, (debugfile, "%s\n", Errorbuf));
+  dprint (1, (debugfile, "%s\n", scratch));
   mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+                     0, COLS-2, 0, 0, scratch, sizeof (scratch), 0);
 
   if (!option (OPTKEEPQUIET))
   {
@@ -306,13 +307,14 @@ void mutt_curses_error (const char *fmt, ...)
 void mutt_curses_message (const char *fmt, ...)
 {
   va_list ap;
+  char scratch[LONG_STRING];
 
   va_start (ap, fmt);
-  vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
+  vsnprintf (scratch, sizeof (scratch), fmt, ap);
   va_end (ap);
 
   mutt_format_string (Errorbuf, sizeof (Errorbuf),
-                     0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0);
+                     0, COLS-2, 0, 0, scratch, sizeof (scratch), 0);
 
   if (!option (OPTKEEPQUIET))
   {
@@ -655,6 +657,9 @@ void mutt_format_string (char *dest, size_t destlen,
   {
     if (k == (size_t)(-1) || k == (size_t)(-2))
     {
+      if (k == (size_t)(-1) && errno == EILSEQ)
+       memset (&mbstate1, 0, sizeof (mbstate1));
+
       k = (k == (size_t)(-1)) ? 1 : n;
       wc = replacement_char ();
     }
@@ -764,6 +769,8 @@ void mutt_paddstr (int n, const char *s)
   {
     if (k == (size_t)(-1) || k == (size_t)(-2))
     {
+      if (k == (size_t) (-1))
+       memset (&mbstate, 0, sizeof (mbstate));
       k = (k == (size_t)(-1)) ? 1 : len;
       wc = replacement_char ();
     }
diff --git a/enter.c b/enter.c
index ff86aa023bd7991683149dc1056496f7de3bca9d..fd7da9d06d192794526e67ba2443d21c36241b6d 100644 (file)
--- a/enter.c
+++ b/enter.c
@@ -129,16 +129,30 @@ size_t my_mbstowcs (wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf)
   size_t wbuflen;
 
   wbuf = *pwbuf, wbuflen = *pwbuflen;
-  memset (&st, 0, sizeof (st));
-  for (; (k = mbrtowc (&wc, buf, MB_LEN_MAX, &st)) &&
-        k != (size_t)(-1) && k != (size_t)(-2); buf += k)
+  
+  while (*buf)
   {
-    if (i >= wbuflen)
+    memset (&st, 0, sizeof (st));
+    for (; (k = mbrtowc (&wc, buf, MB_LEN_MAX, &st)) &&
+        k != (size_t)(-1) && k != (size_t)(-2); buf += k)
+    {
+      if (i >= wbuflen)
+      {
+       wbuflen = i + 20;
+       safe_realloc (&wbuf, wbuflen * sizeof (*wbuf));
+      }
+      wbuf[i++] = wc;
+    }
+    if (*buf && (k == (size_t) -1 || k == (size_t) -2))
     {
-      wbuflen = i + 20;
-      safe_realloc (&wbuf, wbuflen * sizeof (*wbuf));
+      if (i >= wbuflen) 
+      {
+       wbuflen = i + 20;
+       safe_realloc (&wbuf, wbuflen * sizeof (*wbuf));
+      }
+      wbuf[i++] = replacement_char();
+      buf++;
     }
-    wbuf[i++] = wc;
   }
   *pwbuf = wbuf, *pwbuflen = wbuflen;
   return i;
diff --git a/menu.c b/menu.c
index cbb3a8db97cd909ac929a5a4883a6b76af414d89..e9ac6fcc8de13fd63def1e58f91f2429a2910449 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -156,11 +156,13 @@ static void menu_make_entry (char *s, int l, MUTTMENU *menu, int i)
 
 void menu_pad_string (char *s, size_t n)
 {
+  char *scratch = safe_strdup (s);
   int shift = option (OPTARROWCURSOR) ? 3 : 0;
   int cols = COLS - shift;
 
-  mutt_format_string (s, n, cols, cols, 0, ' ', s, strlen (s), 1);
+  mutt_format_string (s, n, cols, cols, 0, ' ', scratch, strlen (scratch), 1);
   s[n - 1] = 0;
+  safe_free (&scratch);
 }
 
 void menu_redraw_full (MUTTMENU *menu)