]> diplodocus.org Git - nmh/commitdiff
Replace non-ASCII characters in headers with ?'s with non-UTF8 locale.
authorDavid Levine <levinedl@acm.org>
Thu, 3 Nov 2016 00:24:32 +0000 (20:24 -0400)
committerDavid Levine <levinedl@acm.org>
Thu, 3 Nov 2016 00:24:32 +0000 (20:24 -0400)
test/mhl/test-rfc6532
uip/mhlsbr.c

index 05dae7b..378d41c 100755 (executable)
@@ -81,19 +81,30 @@ Subject: Blåbærsy
 MIME-Version: 1.0'
 
 
 MIME-Version: 1.0'
 
 
-# check with incompatible locale
-# This is here as a place holder.  We should either try to run the (8-bit) text
-# through iconv, or refuse to display it if the locale is incompatible.  In the
-# case of EAI, that means not UTF-8.
-# start_test 'incompatible locale'
-# LC_ALL=C
-# run_test "$mhl -form mhl.headers `mhpath last`" \
-# 'Date:    20 May 2014 14:28:51 +0200
-# To:      recipientæ@example.com
-# From:    sender??@example.com
-# Subject: Bl??b??rsyltet??y
-#
-# MIME-Version: 1.0'
+start_test 'incompatible locale'
+# Show that LC_CTYPE is sufficient, if LC_ALL is unset.
+unset LC_ALL
+LC_CTYPE=C
+cat >"$MH_TEST_DIR/test.format" <<EOF
+; Doesn't decode From: or Subject:, to be really sure
+; that character replacement works.
+overflowtext="***",overflowoffset=5
+leftadjust,compwidth=9
+Date:formatfield="%<(nodate{text})%{text}%|%(pretty{text})%>"
+To:
+cc:
+From:
+Subject:
+EOF
+
+run_test "$mhl -form "$MH_TEST_DIR/test.format" `mhpath last`" \
+'Date:    20 May 2014 14:28:51 +0200
+To:      recipient??@example.com,
+        recipient2@example.com
+cc:      recip--??@example.com
+From:    sender--??@example.com
+Subject: Bl??b??rsyltet??y'
+rm -f "$MH_TEST_DIR/test.format"
 
 
 finish_test
 
 
 finish_test
index 5a6401e..093a2db 100644 (file)
@@ -94,7 +94,8 @@ DEFINE_SWITCH_ARRAY(MHL, mhlswitches);
 #define NOWRAP      0x040000   /* Don't wrap lines ever             */
 #define FMTFILTER   0x080000   /* Filter through format filter      */
 #define INVISIBLE   0x100000   /* count byte in display columns?    */
 #define NOWRAP      0x040000   /* Don't wrap lines ever             */
 #define FMTFILTER   0x080000   /* Filter through format filter      */
 #define INVISIBLE   0x100000   /* count byte in display columns?    */
-#define        LBITS   "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT\017RTRIM\021SPLIT\022NONEWLINE\023NOWRAP\024FMTFILTER\025INVISIBLE"
+#define FORCE7BIT   0x200000   /* don't display 8-bit bytes         */
+#define        LBITS   "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT\017RTRIM\021SPLIT\022NONEWLINE\023NOWRAP\024FMTFILTER\025INVISIBLE\026FORCE7BIT"
 #define        GFLAGS  (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT | NOWRAP)
 
 /*
 #define        GFLAGS  (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS | SPLIT | NOWRAP)
 
 /*
@@ -1287,6 +1288,13 @@ putcomp (struct mcomp *c1, struct mcomp *c2, int flag)
     char *trimmed_prefix;
     int count, cchdr;
     char *cp;
     char *trimmed_prefix;
     int count, cchdr;
     char *cp;
+    const int utf8 = strcasecmp(get_charset(), "UTF-8") == 0;
+
+    if (! utf8  &&  flag != BODYCOMP) {
+        /* Don't print 8-bit bytes in header field values if not in a
+           UTF-8 locale, as required by RFC 6532. */
+       c1->c_flags |= FORCE7BIT;
+    }
 
     text = c1->c_text ? c1->c_text : c1->c_name;
     /* Create a copy with trailing whitespace trimmed, for use with
 
     text = c1->c_text ? c1->c_text : c1->c_name;
     /* Create a copy with trailing whitespace trimmed, for use with
@@ -1561,9 +1569,24 @@ putch (char ch, long flags)
                putchar ('-');
                putchar (' ');
            }
                putchar ('-');
                putchar (' ');
            }
-            if ((flags & INVISIBLE) == 0) {
-                /* If multibyte character, its first byte only. */
-                ++column;
+            /*
+             * Increment the character count, unless
+             * 1) In UTF-8 locale, this is other than the last byte of
+                  a multibyte character, or
+             * 2) In C locale, will print a non-printable character.
+             */
+            if ((flags & FORCE7BIT) == 0) {
+                /* UTF-8 locale */
+                if ((flags & INVISIBLE) == 0) {
+                    /* If multibyte character, its first byte only. */
+                    ++column;
+                }
+            } else {
+                /* If not an ASCII character, the replace character will be
+                   displayed.  Count it. */
+                if (! isascii((unsigned char) ch) || isprint((unsigned char) ch)) {
+                    ++column;
+                }
             }
            break;
     }
             }
            break;
     }
@@ -1577,7 +1600,11 @@ putch (char ch, long flags)
        return;
     }
 
        return;
     }
 
-    putchar (ch);
+    if (flags & FORCE7BIT  &&  ! isascii((unsigned char) ch)) {
+        putchar ('?');
+    } else {
+        putchar (ch);
+    }
 }
 
 
 }