From: Ralph Corderoy Date: Tue, 25 Apr 2017 23:14:26 +0000 (+0100) Subject: sbr/fmt_scan.c: Only wcwidth(3) a valid mbtowc(3) result. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/fa377c31ac72f5c8253ae96f28185e510c26a720?hp=bacae217c754a3eedd0d71bdda74397c17633123 sbr/fmt_scan.c: Only wcwidth(3) a valid mbtowc(3) result. The assert(3) added by 80a9e99f7078199500d2d53c8d77d1b92af06fbc is failing, but not reproducibly. It's probable that mbtowc() is returning a negative, and not altering wide_char, leaving it as random stack content. Taking its wcwidth() then sometimes also returns negative, causing the assert() failure. Initialising wide_char before the call isn't a solution as it isn't documented if it's modified to an invalid value on an error return. Instead, delay calculating the wcwidth() until after the possible substitution of "?". Leave the assert() in place. --- diff --git a/sbr/fmt_scan.c b/sbr/fmt_scan.c index de1e0806..9377b393 100644 --- a/sbr/fmt_scan.c +++ b/sbr/fmt_scan.c @@ -256,16 +256,15 @@ cpstripped (charstring_t dest, size_t max, char *str) while (*str != '\0' && len > 0 && max > 0) { #ifdef MULTIBYTE_SUPPORT char_len = mbtowc(&wide_char, str, len); - w = wcwidth(wide_char); /* * If mbrtowc() failed, then we have a character that isn't valid - * in the current encoding. Replace it with a '?'. We do that by + * in the current encoding, or len wasn't enough for the whole + * multi-byte rune to be read. Replace it with a '?'. We do that by * setting the alstr variable to the value of the replacement string; * altstr is used below when the bytes are copied into the output * buffer. */ - if (char_len < 0) { altstr = "?"; char_len = mbtowc(&wide_char, altstr, 1); @@ -297,6 +296,7 @@ cpstripped (charstring_t dest, size_t max, char *str) prevCtrl = 0; #ifdef MULTIBYTE_SUPPORT + w = wcwidth(wide_char); assert(w >= 0); if (max >= (size_t) w) { charstring_push_back_chars (dest, altstr ? altstr : str, char_len, w);