Hi David,
it seems quite possible to me that the wcwidth() of a `mbtowc() < 0'
could be -1
wcwidth() should be negative only if wide_char is non-printable. The
code checks if iswcntrl() or iswspace()
But only by the time wide_char may have been written by a second
mbtowc(). If the first mbtowc() returns negative then I don't think
it's documented that wide_char has any sane content so it might be
whatever was on the stack, or some partial workings of mbtowc(). I
think the wcwidth() should be delayed until wide_char stops changing.
I've a local commit here that does that, but it's held up by other
commits and my git-fu isn't up to selective pushing.
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);
--
Cheers, Ralph.
https://plus.google.com/+RalphCorderoy
_______________________________________________
Nmh-workers mailing list
Nmh-workers(_at_)nongnu(_dot_)org
https://lists.nongnu.org/mailman/listinfo/nmh-workers