From: Thomas Roessler Date: Thu, 7 Dec 2006 11:34:34 +0000 (+0000) Subject: - my_mbtowcs didn't recover from bad multibyte sequences X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03cff2c7f40e59dd80bd485c1b28876d9a951076;p=neomutt - my_mbtowcs didn't recover from bad multibyte sequences - 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. --- diff --git a/commands.c b/commands.c index 8ec7c107e..6f99cbc93 100644 --- a/commands.c +++ b/commands.c @@ -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) { diff --git a/curs_lib.c b/curs_lib.c index 169168ea3..57bf78080 100644 --- a/curs_lib.c +++ b/curs_lib.c @@ -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 ff86aa023..fd7da9d06 100644 --- 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 cbb3a8db9..e9ac6fcc8 100644 --- 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)