nmh-workers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Nmh-workers] sbr/fmt_scan.c: cpstripped(): assert(w >= 0) Failure.


From: Ralph Corderoy
Subject: Re: [Nmh-workers] sbr/fmt_scan.c: cpstripped(): assert(w >= 0) Failure.
Date: Wed, 26 Apr 2017 00:37:10 +0100

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]