From: Ken Hornstein Date: Sat, 19 Mar 2016 04:06:24 +0000 (-0400) Subject: Recover properly if the character conversion fails. X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/adfed5f72bc07ac7de8dfc62188338d4d4f25a38 Recover properly if the character conversion fails. --- diff --git a/uip/mhshowsbr.c b/uip/mhshowsbr.c index 056c2f45..02b36412 100644 --- a/uip/mhshowsbr.c +++ b/uip/mhshowsbr.c @@ -1080,6 +1080,7 @@ convert_charset (CT ct, char *dest_charset, int *message_mods) { char *dest_buffer = mh_xmalloc(dest_buffer_size); HF hf; char *tempfile; + int fromutf8 = !strcasecmp(src_charset, "UTF-8"); if ((conv_desc = iconv_open (dest_charset, src_charset)) == (iconv_t) -1) { @@ -1149,6 +1150,30 @@ iconv_start: outbytes_before += bumpup; goto iconv_start; } + if (errno == EINVAL) { + /* middle of multi-byte sequence */ + write (fd, dest_buffer, outbytes_before - outbytes); + fseeko (*fp, -inbytes, SEEK_CUR); + if (end > 0) bytes_to_read += inbytes; + /* advise(NULL, "convert_charset: EINVAL"); */ + continue; + } + if (errno == EILSEQ) { + /* invalid multi-byte sequence */ + if (fromutf8) { + for (++ib, --inbytes; + inbytes > 0 && + (((unsigned char) *ib) & 0xc0) == 0x80; + ++ib, --inbytes) + continue; + } else { + ib++; inbytes--; /* skip it */ + } + (*ob++) = '?'; outbytes --; + /* advise(NULL, "convert_charset: EILSEQ"); */ + goto iconv_start; + } + advise (NULL, "convert_charset: errno = %d", errno); status = NOTOK; break; } else {