changeset: 6590:c8c76a6a1e61 user: Karel Zak <k...@redhat.com> date: Sun Mar 20 17:06:16 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/c8c76a6a1e61
Improve error handling in mutt_wstr_trunc(). This is Karel Zak's patch to fix handling of (illegal) multi-byte chars. * mutt_wstr_trunc(): Reset mbstate after error in mbrtowc(). Set wc=0 if wcwidth returns < 0. Addresses: https://github.com/karelzak/mutt-kz/issues/58 Thanks to Richard Russon for bringing this patch to our attention. changeset: 6591:a3450fd50d11 user: Kevin McCarthy <ke...@8t8.us> date: Tue Mar 22 18:00:13 2016 -0700 link: http://dev.mutt.org/hg/mutt/rev/a3450fd50d11 Clean up mutt_wstr_trunc() some more. * Change return type to size_t. The return value is the cumulation of values from mbrtowc(), which returns size_t. All callers already assign the return value to a size_t, requiring no external changes. * Change the local variables n, w, l, and cl to size_t. n is the strlen of the src parameter. l and cl are used for the return value. w is assigned to the *width parameter, which is size_t. cw is kept as an int, because wcwidth returns type int. * Change error handling of mbrtowc to be the same as other functions in mutt: only reset mbstate when the retval==-1. When retvat==-2, set cl=n to break out of the loop. Also, set wc to replacement_char and allow the logic below to determine the width instead of hardcoding to 1. diffs (57 lines): diff -r b302f9868d78 -r a3450fd50d11 curs_lib.c --- a/curs_lib.c Tue Mar 22 12:35:54 2016 -0700 +++ b/curs_lib.c Tue Mar 22 18:00:13 2016 -0700 @@ -949,11 +949,11 @@ /* See how many bytes to copy from string so its at most maxlen bytes * long and maxwid columns wide */ -int mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width) +size_t mutt_wstr_trunc (const char *src, size_t maxlen, size_t maxwid, size_t *width) { wchar_t wc; - int w = 0, l = 0, cl; - int cw, n; + size_t n, w = 0, l = 0, cl; + int cw; mbstate_t mbstate; if (!src) @@ -965,15 +965,19 @@ for (w = 0; n && (cl = mbrtowc (&wc, src, n, &mbstate)); src += cl, n -= cl) { if (cl == (size_t)(-1) || cl == (size_t)(-2)) - cw = cl = 1; - else { - cw = wcwidth (wc); - /* hack because M_TREE symbols aren't turned into characters - * until rendered by print_enriched_string (#3364) */ - if (cw < 0 && cl == 1 && src[0] && src[0] < M_TREE_MAX) - cw = 1; + if (cl == (size_t)(-1)) + memset (&mbstate, 0, sizeof (mbstate)); + cl = (cl == (size_t)(-1)) ? 1 : n; + wc = replacement_char (); } + cw = wcwidth (wc); + /* hack because M_TREE symbols aren't turned into characters + * until rendered by print_enriched_string (#3364) */ + if (cw < 0 && cl == 1 && src[0] && src[0] < M_TREE_MAX) + cw = 1; + else if (cw < 0) + cw = 0; /* unprintable wchar */ if (cl + l > maxlen || cw + w > maxwid) break; l += cl; diff -r b302f9868d78 -r a3450fd50d11 protos.h --- a/protos.h Tue Mar 22 12:35:54 2016 -0700 +++ b/protos.h Tue Mar 22 18:00:13 2016 -0700 @@ -356,7 +356,7 @@ int mutt_smtp_send (const ADDRESS *, const ADDRESS *, const ADDRESS *, const ADDRESS *, const char *, int); #endif -int mutt_wstr_trunc (const char *, size_t, size_t, size_t *); +size_t mutt_wstr_trunc (const char *, size_t, size_t, size_t *); int mutt_charlen (const char *s, int *); int mutt_strwidth (const char *); int mutt_compose_menu (HEADER *, char *, size_t, HEADER *, int);