]> diplodocus.org Git - nmh/blobdiff - test/mhfixmsg/test-mhfixmsg
Allow -decodetext binary, though 8bit is still the default because
[nmh] / test / mhfixmsg / test-mhfixmsg
index 497fd87a34a6bf43517ac13f24243921b69f1f6e..efe7de7e9e390ce79051dea15220003e3853a34a 100755 (executable)
@@ -12,52 +12,68 @@ if test -z "${MH_OBJ_DIR}"; then
     MH_OBJ_DIR=`cd $srcdir && pwd`; export MH_OBJ_DIR
 fi
 
-. "${srcdir}/test/post/test-post-common.sh"
+. "${MH_OBJ_DIR}/test/common.sh"
 
+setup_test
+
+#### Make sure that html-to-text conversion is what we expect.
+require_locale en_US.utf-8 en_US.utf8
+LC_ALL=en_US.UTF-8; export LC_ALL
 
 expected="$MH_TEST_DIR/test-mhfixmsg$$.expected"
 expected_err="$MH_TEST_DIR/test-mhfixmsg$$.expected_err"
 actual="$MH_TEST_DIR/test-mhfixmsg$$.actual"
 actual_err="$MH_TEST_DIR/test-mhfixmsg$$.actual_err"
 
-set +e
-if grep mhfixmsg-format-text/html "${MH_TEST_DIR}/Mail/mhn.defaults" \
+mhn_defaults="$MH_INST_DIR${nmhetcdir}/mhn.defaults"
+
+if grep mhfixmsg-format-text/html "${mhn_defaults}" \
   >/dev/null; then
   can_reformat_texthtml=1
+  if grep 'mhfixmsg-format-text/html.*w3m' "${mhn_defaults}" \
+    >/dev/null; then
+    #### w3m uses $HOME/.w3m/, and creates it if it doesn't exist.  To
+    #### support testing with non-writeable $HOME, and to not leave
+    #### relics from this test if it is writeable but doesn't already
+    #### have a .w3m, and to not depend on whatever is in that if it
+    #### does already exist, overwrite $HOME if using w3m.
+    HOME="$MHTMPDIR"; export HOME
+  fi
 else
-  echo "$0: skipping -reformat check because
-    mhfixmsg-format-text/html is not available"
+  echo "$0: skipping -reformat check because no text browser was found"
   can_reformat_texthtml=0
 fi
-set -e
 
 
 # check -help
-# Verified behavior consistent with compiled sendmail.
 cat >"$expected" <<EOF
 Usage: mhfixmsg [+folder] [msgs] [switches]
   switches are:
-  -decodetext 8bit|7bit
+  -decodetext 8bit|7bit|binary
   -nodecodetext
-  -[no]textcodeset
+  -decodetypes
+  -[no]crlflinebreaks
+  -[no]textcharset
   -[no]reformat
+  -[no]replacetextplain
   -[no]fixboundary
   -[no]fixcte
+  -fixtype mimetype
   -file file
   -outfile file
   -rmmproc program
   -normmproc
+  -[no]changecur
   -[no]verbose
   -version
   -help
 EOF
 
-mhfixmsg -help >"$actual" 2>&1
+run_prog mhfixmsg -help >"$actual" 2>&1
 check "$expected" "$actual"
 
 
 # check -version
-# Verified same behavior as compiled mhfixmsg.
 case `mhfixmsg -version` in
   mhfixmsg\ --*) ;;
   *) printf '%s: mhfixmsg -version generated unexpected output\n' "$0" >&2
@@ -177,7 +193,7 @@ check "$MH_TEST_DIR"/Mail/inbox/,11 "$MH_TEST_DIR"/Mail/inbox/11.original
 # check -reformat (enabled by default):  addition of text/plain part
 # to solitary text/html part
 #
-cat >"$expected" <<EOF
+prepare_space >"$expected" <<EOF
 MIME-Version: 1.0
 From: sender@example.com
 To: bonquiqui@example.com
@@ -239,16 +255,23 @@ if [ $can_reformat_texthtml -eq 1 ]; then
 mhfixmsg: 12 part 1, decode text/html; charset=\"Windows-1252\"" \
        >"$expected.err"
 
-  #### lynx inserts multiple blank lines, so use uniq to squeeze them.
-  mhfixmsg last -outfile - -verbose 2>"$actual.err" | uniq >"$actual"
-  check "$expected" "$actual"
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -outfile - -verbose 2>"$actual.err" | \
+    squeeze_lines >"$actual"
+  check "$expected" "$actual" 'ignore space'
   check "$expected.err" "$actual.err"
+else
+  rm -f "$expected"
 fi
 
 
+# check implicit -file with absolute pathname
+run_test "mhfixmsg `mhpath last` -outfile /dev/null" ''
+
+
 # check handling of boundary string that appears in message body
 #
-cat >"$expected" <<EOF
+prepare_space >"$expected" <<EOF
 MIME-Version: 1.0
 From: sender@example.com
 To: bonquiqui@example.com
@@ -314,15 +337,18 @@ if [ $can_reformat_texthtml -eq 1 ]; then
 mhfixmsg: 12 part 1, decode text/html; charset=\"Windows-1252\"" \
        >"$expected.err"
 
-  #### lynx inserts multiple blank lines, so use uniq to squeeze them.
-  mhfixmsg last -outfile - -verbose 2>"$actual.err" | uniq >"$actual"
-  check "$expected" "$actual"
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -outfile - -verbose 2>"$actual.err" | \
+    squeeze_lines >"$actual"
+  check "$expected" "$actual" 'ignore space'
   check "$expected.err" "$actual.err"
+else
+  rm -f "$expected"
 fi
 
 
 # check -nodecode
-cat >"$expected" <<EOF
+prepare_space >"$expected" <<EOF
 MIME-Version: 1.0
 From: sender@example.com
 To: bonquiqui@example.com
@@ -384,18 +410,21 @@ EOF
 if [ $can_reformat_texthtml -eq 1 ]; then
   printf '%s\n' 'mhfixmsg: 12, insert text/plain part' >"$expected.err"
 
-  #### lynx inserts multiple blank lines, so use uniq to squeeze them.
-  mhfixmsg last -nodecode -outfile - -verbose 2>"$actual.err" | uniq >"$actual"
-  check "$expected" "$actual"
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -nodecode -outfile - -verbose 2>"$actual.err" | \
+    squeeze_lines >"$actual"
+  check "$expected" "$actual" 'ignore space'
   check "$expected.err" "$actual.err"
+else
+  rm -f "$expected"
 fi
 
 
-# check -decode (enabled by default)
+# check -decodetext (enabled by default)
 cat >"$expected" <<EOF
 To: recipient@example.com
 From: sender@example.com
-Subject: mhfixmsg decode test
+Subject: mhfixmsg decode test 1
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
 
@@ -412,7 +441,7 @@ EOF
 cat >`mhpath new` <<EOF
 To: recipient@example.com
 From: sender@example.com
-Subject: mhfixmsg decode test
+Subject: mhfixmsg decode test 1
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
 
@@ -426,11 +455,11 @@ VGhpcyBpcyBhIHRleHQvcGxhaW4gcGFydC4K
 ------- =_aaaaaaaaaa0--
 EOF
 
-mhfixmsg last -outfile "$actual"
+run_prog mhfixmsg last -outfile "$actual"
 check "$expected" "$actual"
 
 
-# check -decode with more complicated content structure
+# check -decodetext with more complicated content structure
 cat >$expected <<EOF
 To: recipient@example.com
 From: sender@example.com
@@ -442,8 +471,7 @@ This is additional content before the first subpart of the multipart.
 
 ------- =_aaaaaaaaaa0
 Content-Type: multipart/related;
-    type="multipart/alternative";
-    boundary="subpart__1.1"
+    type="text/plain"; boundary="subpart__1.1"
 
 --subpart__1.1
 Content-Type: text/plain; charset="iso-8859-1"
@@ -492,8 +520,7 @@ This is additional content before the first subpart of the multipart.
 
 ------- =_aaaaaaaaaa0
 Content-Type: multipart/related;
-    type="multipart/alternative";
-    boundary="subpart__1.1"
+    type="text/plain"; boundary="subpart__1.1"
 
 --subpart__1.1
 Content-Type: text/plain; charset="iso-8859-1"
@@ -530,60 +557,172 @@ VGhpcyBpcyB0aGUgZm91cnRoIHRleHQvcGxhaW4gcGFydC4K
 
 This is additional content after the last subpart of the multipart.
 EOF
-mhfixmsg last -outfile "$actual"
+run_prog mhfixmsg last -outfile "$actual"
 check "$expected" "$actual"
 
 
-# check attempted -decode of binary text
+# check attempted (default, 8 bit) -decodetext of binary text
 #### Generated the encoded text below with:
-####   $ printf '\x0d\xbd\xb2=\xbc\n' | base64
+####   $ printf '\xbd\xb2=\xbc\x00\n' | base64
 cat >`mhpath new` <<EOF
 To: recipient@example.com
 From: sender@example.com
-Subject: mhfixmsg attempted binary decode test
+Subject: mhfixmsg binary decode test
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
 
 ------- =_aaaaaaaaaa0
-Content-Type: text/plain; charset="iso-8859-1"; name="square.txt"
+Content-Type: text/plain; charset=UTF-8; name="nul+square.txt"
 Content-Transfer-Encoding: base64
 
-Db2yPbwK
+vbI9vAAK
 
 ------- =_aaaaaaaaaa0--
 EOF
 
 cp -p `mhpath last` "$expected"
-set +e
-mhfixmsg last
-set -e
+run_prog mhfixmsg last
+check `mhpath last` "$expected" 'keep first'
+
+
+# check for successful decode of a different part with attempted -decodetext
+# of binary (>998 characters) text
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg successful decode of text/plain with failed binary decode
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: 8bit
+
+This is a text plain part
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="ascii"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline
+
+PGh0bWw+PGhlYWQ+PHRpdGxlPmxvbmcgbGluZTwvdGl0bGU+PC9oZWFkPjxib2R5PlRoaXMgbGlu
+ZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBhcnQg
+c2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTggY2hh
+cmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQuICBU
+aGlzIGxpbmUgaXMgZ3JlYXRlciB0aGFuIDk5OCBjaGFyYWN0ZXJzIGluIGxlbmd0aCwgc28gdGhp
+cyBwYXJ0IHNob3VsZCBub3QgYmUgZGVjb2RlZC4gIFRoaXMgbGluZSBpcyBncmVhdGVyIHRoYW4g
+OTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBhcnQgc2hvdWxkIG5vdCBiZSBkZWNv
+ZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTggY2hhcmFjdGVycyBpbiBsZW5ndGgs
+IHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQuICBUaGlzIGxpbmUgaXMgZ3JlYXRl
+ciB0aGFuIDk5OCBjaGFyYWN0ZXJzIGluIGxlbmd0aCwgc28gdGhpcyBwYXJ0IHNob3VsZCBub3Qg
+YmUgZGVjb2RlZC4gIFRoaXMgbGluZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4g
+bGVuZ3RoLCBzbyB0aGlzIHBhcnQgc2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlz
+IGdyZWF0ZXIgdGhhbiA5OTggY2hhcmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91
+bGQgbm90IGJlIGRlY29kZWQuICBUaGlzIGxpbmUgaXMgZ3JlYXRlciB0aGFuIDk5OCBjaGFyYWN0
+ZXJzIGluIGxlbmd0aCwgc28gdGhpcyBwYXJ0IHNob3VsZCBub3QgYmUgZGVjb2RlZC4gIFRoaXMg
+bGluZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBh
+cnQgc2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTgg
+Y2hhcmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQu
+ICA8L2JvZHk+PC9odG1sPg==
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg successful decode of text/plain with failed binary decode
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: base64
+
+VGhpcyBpcyBhIHRleHQgcGxhaW4gcGFydAo=
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="ascii"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline
+
+PGh0bWw+PGhlYWQ+PHRpdGxlPmxvbmcgbGluZTwvdGl0bGU+PC9oZWFkPjxib2R5PlRoaXMgbGlu
+ZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBhcnQg
+c2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTggY2hh
+cmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQuICBU
+aGlzIGxpbmUgaXMgZ3JlYXRlciB0aGFuIDk5OCBjaGFyYWN0ZXJzIGluIGxlbmd0aCwgc28gdGhp
+cyBwYXJ0IHNob3VsZCBub3QgYmUgZGVjb2RlZC4gIFRoaXMgbGluZSBpcyBncmVhdGVyIHRoYW4g
+OTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBhcnQgc2hvdWxkIG5vdCBiZSBkZWNv
+ZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTggY2hhcmFjdGVycyBpbiBsZW5ndGgs
+IHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQuICBUaGlzIGxpbmUgaXMgZ3JlYXRl
+ciB0aGFuIDk5OCBjaGFyYWN0ZXJzIGluIGxlbmd0aCwgc28gdGhpcyBwYXJ0IHNob3VsZCBub3Qg
+YmUgZGVjb2RlZC4gIFRoaXMgbGluZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4g
+bGVuZ3RoLCBzbyB0aGlzIHBhcnQgc2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlz
+IGdyZWF0ZXIgdGhhbiA5OTggY2hhcmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91
+bGQgbm90IGJlIGRlY29kZWQuICBUaGlzIGxpbmUgaXMgZ3JlYXRlciB0aGFuIDk5OCBjaGFyYWN0
+ZXJzIGluIGxlbmd0aCwgc28gdGhpcyBwYXJ0IHNob3VsZCBub3QgYmUgZGVjb2RlZC4gIFRoaXMg
+bGluZSBpcyBncmVhdGVyIHRoYW4gOTk4IGNoYXJhY3RlcnMgaW4gbGVuZ3RoLCBzbyB0aGlzIHBh
+cnQgc2hvdWxkIG5vdCBiZSBkZWNvZGVkLiAgVGhpcyBsaW5lIGlzIGdyZWF0ZXIgdGhhbiA5OTgg
+Y2hhcmFjdGVycyBpbiBsZW5ndGgsIHNvIHRoaXMgcGFydCBzaG91bGQgbm90IGJlIGRlY29kZWQu
+ICA8L2JvZHk+PC9odG1sPg==
+
+------- =_aaaaaaaaaa0--
+EOF
+
+run_prog mhfixmsg -noreformat last
 check `mhpath last` "$expected" 'keep first'
 
 
-# check -decode of binary text
-printf "%s\x0d\xbd\xb2=\xbc%s" "To: recipient@example.com
+# check for successful decode of a different part with -decodetext of binary
+# (>998 characters) text
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg successful decode of text/plain with failed binary decode
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: 8bit
+
+This is a text plain part
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="ascii"
+Content-Transfer-Encoding: binary
+Content-Disposition: inline
+
+<html><head><title>long line</title></head><body>This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  This line is greater than 998 characters in length, so this part should not be decoded.  </body></html>
+
+------- =_aaaaaaaaaa0--
+EOF
+
+run_prog mhfixmsg -noreformat -decodetext binary last
+check `mhpath last` "$expected"
+
+
+# check -decodetext of binary (containing ASCII NUL) text
+printf "%s\xbd\xb2=\xbc\x00%s" "To: recipient@example.com
 From: sender@example.com
 Subject: mhfixmsg binary decode test
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary=\"----- =_aaaaaaaaaa0\"
 
 ------- =_aaaaaaaaaa0
-Content-Type: text/plain; charset=\"iso-8859-1\"; name=\"square.txt\"
+Content-Type: text/plain; charset=UTF-8; name=\"nul+square.txt\"
 Content-Transfer-Encoding: binary
 
 " "
 
 ------- =_aaaaaaaaaa0--
 " >"$expected"
-## output_content() in mhoutsbr.c can't handle binary content.
-## mhfixmsg last -decodetext binary -outfile "$actual"
-## check "$expected" "$actual"
-rm -f "$expected"
-rmm last
+mhfixmsg last -decodetext binary -outfile "$actual"
+check "$expected" "$actual"
 
 
 # check that -reformat succeeds when decode of binary text fails
-cat >"$expected" <<'EOF'
+prepare_space >"$expected" <<'EOF'
 MIME-Version: 1.0
 Date: Thu, 11 Apr 2013 02:47:08 -0700
 To: <me@example.com>
@@ -606,30 +745,6 @@ Content-Type: text/html; charset="ISO-8859-1"
 Content-Transfer-Encoding: quoted-printable
 
 <body>
-<table width=3D"325" border=3D"0" cellspacing=3D"0" cellpadding=3D"0">
-<tr><td><font face=3D"Arial, Helvetica, sans-serif" color=3D"#333333" size=
-=3D"2"><strong>Mile</strong></font></td><td height=3D"3">&nbsp;</td><td al=
-ign=3D"right"><font face=3D"Arial, Helvetica, sans-serif" color=3D"#333333=
-" size=3D"2">$0.00</font></td></tr><tr><td><font face=3D"Arial, Helvetica,=
- sans-serif" color=3D"#333333" size=3D"2"><strong>Time</strong></font></td=
-><td height=3D"3">&nbsp;</td><td align=3D"right"><font face=3D"Arial, Helv=
-etica, sans-serif" color=3D"#333333" size=3D"2">$78.71</font></td></tr><tr=
-><td><font face=3D"Arial, Helvetica, sans-serif" color=3D"#333333" size=3D=
-"2"><strong>State Tax</strong></font></td><td height=3D"3">&nbsp;</td><td =
-align=3D"right"><font face=3D"Arial, Helvetica, sans-serif" color=3D"#3333=
-33" size=3D"2">$5.90</font></td></tr><tr><td><font face=3D"Arial, Helvetic=
-a, sans-serif" color=3D"#333333" size=3D"2"><strong>Vehicle License Fee</s=
-trong></font></td><td height=3D"3">&nbsp;</td><td align=3D"right"><font fa=
-ce=3D"Arial, Helvetica, sans-serif" color=3D"#333333" size=3D"2">$1.84</fo=
-nt></td></tr><tr><td><font face=3D"Arial, Helvetica, sans-serif" color=3D"=
-#333333" size=3D"2"><strong>State Txn Tax</strong></font></td><td height=3D=
-"3">&nbsp;</td><td align=3D"right"><font face=3D"Arial, Helvetica, sans-se=
-rif" color=3D"#333333" size=3D"2">$6.00</font></td></tr>
-
-</body>
-</html>
-
-------=_nmh-multipart--
 EOF
 
 cat >`mhpath new` <<'EOF'
@@ -667,23 +782,24 @@ d><td align=3D"right"><font face=3D"Arial, Helvetica, sans-serif" color=3D"=
 EOF
 
 if [ $can_reformat_texthtml -eq 1 ]; then
-  #### lynx inserts multiple blank lines, so use uniq to squeeze them.
-  mhfixmsg last -outfile - | uniq >"$actual"
-# ????  check "$expected" "$actual" 'ignore space'
-  /bin/rm "$expected" "$actual"
+  #### lynx inserts multiple blank lines, so squeeze them.
+  #### Truncate to avoid comparing the html portion because it can
+  #### get reformatted.
+  run_prog mhfixmsg last -outfile - | squeeze_lines | head -22 >"$actual"
+  check "$expected" "$actual" 'ignore space'
 else
   cp -p "$MH_TEST_DIR/Mail/inbox/15" "$MH_TEST_DIR/Mail/inbox/15.backup"
   rm -f "$expected"
 fi
 
 
-# check -textcodeset
+# check -textcharset
 # Also checks preservation of attributes after one (charset) that is
 # modified.
 cat >"$expected" <<EOF
 To: recipient@example.com
 From: sender@example.com
-Subject: mhfixmsg textcodeset test
+Subject: mhfixmsg textcharset test
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
 
@@ -702,7 +818,7 @@ EOF
 cat >`mhpath new` <<EOF
 To: recipient@example.com
 From: sender@example.com
-Subject: mhfixmsg textcodeset test
+Subject: mhfixmsg textcharset test
 MIME-Version: 1.0
 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
 
@@ -716,17 +832,13 @@ vbI9vAo=
 ------- =_aaaaaaaaaa0--
 EOF
 
-set +e
-mhfixmsg last -textcodeset utf-8 -outfile "$actual" 2>"$actual.err"
-if grep "mhfixmsg: Can't convert .* to .* without iconv" "$actual.err" \
-  >/dev/null; then
-  echo skipping -textcodeset check because nmh was built without iconv
-  rm -f "$expected" "$actual" "$actual.err"
-else
+if test "$ICONV_ENABLED" -eq 1; then
+  run_prog mhfixmsg last -textcharset utf-8 -outfile "$actual" 2>&1
   check "$expected" "$actual"
-  rm "$actual.err"
+else
+  echo "$0: skipping -textcharset check because nmh was built without iconv"
+  rm -f "$expected"
 fi
-set -e
 
 
 # check -nofixboundary
@@ -756,11 +868,11 @@ EOF
 cp -p `mhpath last` `mhpath new`
 
 run_test 'mhfixmsg last -nofixboundary' ''
-check "$MH_TEST_DIR"/Mail/inbox/17 "$MH_TEST_DIR"/Mail/inbox/18 'keep first'
+check "$MH_TEST_DIR"/Mail/inbox/18 "$MH_TEST_DIR"/Mail/inbox/19 'keep first'
 
 
 # check that message is not output when fed through stdin
-mhfixmsg -file - -verbose <`mhpath last` >"$actual" 2>"$actual.err"
+run_prog mhfixmsg -file - -verbose <`mhpath last` >"$actual" 2>"$actual.err"
 check "$expected" "$actual"
 if grep "mhfixmsg: $MH_TEST_DIR/Mail/.*, fix multipart boundary" \
    "$actual.err" >/dev/null; then
@@ -777,7 +889,7 @@ fi
 cat >"$expected" <<EOF
 Date: Fri, 13 May 2011 08:21:12 -0500
 Content-Type: multipart/alternative;
-        boundary="----=_NextPart_000_1781A1A_01CC1147.81EBA8D4"
+       boundary="----=_NextPart_000_1781A1A_01CC1147.81EBA8D4"
 Content-Transfer-Encoding: 8bit
 MIME-Version: 1.0
 From: <sender@example.com>
@@ -795,28 +907,47 @@ The boundaries of this part don't match the header boundary.
 EOF
 
 run_test 'mhfixmsg last -outfile '"$actual"' -verbose' \
-         "mhfixmsg: 17, fix multipart boundary"
+         "mhfixmsg: 18, fix multipart boundary"
 check "$expected" "$actual"
 
 
-# check that text/plain part is added to lone text/html in multipart/related
-cat >"$expected" <<EOF
+# check that message is not modified when -fixboundary fails
+cat >`mhpath new` <<EOF
+Date: Fri, 13 May 2011 08:21:12 -0500
+Content-Type: multipart/alternative;
+        boundary="----=_ NextPart_000_1781A17_01CC1147.81E9467A"
+Content-Transfer-Encoding: 8bit
+MIME-Version: 1.0
+From: <sender@example.com>
+To: <recipient@example.com>
+Subject: mhfixmsg bad boundary test
+
+This is a multi-part message in MIME format.
+
+------=_ NextPart_000_1781A1A_01CC1147.81EBA8D4
+Content-Type: text/plain
+
+The boundary below doesn't match the header boundary.
+
+------=_
+NextPart_000_1781A1A_01CC1147.81EBA8D4--
+EOF
+
+cp -p `mhpath last` "$expected"
+run_test "mhfixmsg last -outfile $actual" ''
+check "$expected" "$actual"
+
+
+# check that text/plain part is not added to text/html in multipart/related
+# when it shouldn't be
+cat >`mhpath new` <<EOF
 MIME-Version: 1.0
 Date: Tue, 26 Feb 2013 18:07:20 -0600
 Subject: multipart/related, not /alternative
 Content-Type: multipart/related;
-        boundary="----=_Part_90310_101292502.1"
+        type="text/html"; boundary="----=_Part_90310_101292502.1"
 
 ------=_Part_90310_101292502.1
-Content-Type: multipart/alternative; boundary="----=_nmh-multipart1"
-
-------=_nmh-multipart1
-Content-Type: text/plain; charset="us-ascii"
-Content-Transfer-Encoding: 7bit
-
-This is the real content.
-
-------=_nmh-multipart1
 Content-Type: text/html; charset="us-ascii"
 Content-Transfer-Encoding: 7bit
 
@@ -829,8 +960,6 @@ Content-Transfer-Encoding: 7bit
   </body>
 </html>
 
-------=_nmh-multipart1--
-
 ------=_Part_90310_101292502.1
 Content-Type: text/plain; charset="us-ascii"
 Content-Transfer-Encoding: 7bit
@@ -840,12 +969,30 @@ Your email client does not support HTML messages
 ------=_Part_90310_101292502.1--
 EOF
 
-cat >`mhpath new` <<EOF
+cp -p `mhpath last` "$expected"
+
+if [ $can_reformat_texthtml -eq 1 ]; then
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -outfile - | squeeze_lines >"$actual"
+  check "$expected" "$actual" 'ignore space'
+else
+  rm -f "$expected"
+fi
+
+
+# check that text/plain part is added to text/html in multipart/related
+# when it should be
+cat >"$expected" <<EOF
 MIME-Version: 1.0
 Date: Tue, 26 Feb 2013 18:07:20 -0600
 Subject: multipart/related, not /alternative
-Content-Type: multipart/related;
-        boundary="----=_Part_90310_101292502.1"
+Content-Type: multipart/alternative; boundary="----=_Part_90310_101292502.1"
+
+------=_Part_90310_101292502.1
+Content-Type: text/plain; charset="us-ascii"
+Content-Transfer-Encoding: 7bit
+
+This is the real content.
 
 ------=_Part_90310_101292502.1
 Content-Type: text/html; charset="us-ascii"
@@ -859,18 +1006,37 @@ Content-Transfer-Encoding: 7bit
     This is the real content.
   </body>
 </html>
+
+------=_Part_90310_101292502.1--
+EOF
+
+cat >`mhpath new` <<EOF
+MIME-Version: 1.0
+Date: Tue, 26 Feb 2013 18:07:20 -0600
+Subject: multipart/related, not /alternative
+Content-Type: multipart/related;
+        type="text/html"; boundary="----=_Part_90310_101292502.1"
+
 ------=_Part_90310_101292502.1
-Content-Type: text/plain; charset="us-ascii"
+Content-Type: text/html; charset="us-ascii"
 Content-Transfer-Encoding: 7bit
 
-Your email client does not support HTML messages
+<html><head>
+    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+    <title>HTML Content</title>
+  </head>
+  <body>
+    This is the real content.
+  </body>
+</html>
+
 ------=_Part_90310_101292502.1--
 EOF
 
 if [ $can_reformat_texthtml -eq 1 ]; then
-  #### lynx inserts multiple blank lines, so use uniq to squeeze them.
-  mhfixmsg last -outfile - | uniq >"$actual"
-  check "$expected" "$actual"
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -outfile - | squeeze_lines >"$actual"
+  check "$expected" "$actual" 'ignore space'
 else
   rm -f "$expected"
 fi
@@ -939,6 +1105,33 @@ run_test 'mhfixmsg last -outfile '"$actual" ''
 check "$expected" "$actual"
 
 
+# check not stripping of CRs from ASCII text context (default)
+cat >"$expected" <<EOF
+MIME-Version: 1.0
+From: sender@example.com
+To: recipient@example.com
+Subject: message with CR's
+Date: Mon, 29 Apr 2013 11:51:45 -0400
+
+There are two CR-LF pairs at the end of this sentence.\r
+\r
+EOF
+
+cat >`mhpath new` <<'EOF'
+MIME-Version: 1.0
+From: sender@example.com
+To: recipient@example.com
+Subject: message with CR's
+Date: Mon, 29 Apr 2013 11:51:45 -0400
+
+There are two CR-LF pairs at the end of this sentence.\r
+\r
+EOF
+
+run_prog mhfixmsg last -outfile "$actual"
+check "$expected" "$actual"
+
+
 # check stripping of CRs from ASCII text context
 cat >"$expected" <<EOF
 MIME-Version: 1.0
@@ -947,7 +1140,7 @@ To: recipient@example.com
 Subject: message with CR's
 Date: Mon, 29 Apr 2013 11:51:45 -0400
 
-There are two CR-LF pairs at the end of this sentence.
+There were two CR-LF pairs at the end of this sentence.
 
 EOF
 
@@ -958,11 +1151,168 @@ To: recipient@example.com
 Subject: message with CR's
 Date: Mon, 29 Apr 2013 11:51:45 -0400
 
-There are two CR-LF pairs at the end of this sentence.\r
+There were two CR-LF pairs at the end of this sentence.\r
 \r
 EOF
 
-mhfixmsg last -outfile "$actual"
+run_prog mhfixmsg last -outfile "$actual" -nocrlflinebreaks
+check "$expected" "$actual"
+
+
+# check -replacetextplain
+prepare_space >"$expected" <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg replacement of bad text/plain part test
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="----=_Part_876302"
+
+------=_Part_876302
+Content-Type: text/plain; charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+
+Yes, the text/plain part really was empty.
+
+------=_Part_876302
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<html><head>
+<title>eticket</title>
+</head>
+<body>
+  Yes, the text/plain part really was empty.
+</body>
+</html>
+
+------=_Part_876302--
+EOF
+
+cat >`mhpath new` <<'EOF'
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg replacement of bad text/plain part test
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="----=_Part_876302"
+
+------=_Part_876302
+Content-Type: text/plain; charset="iso-8859-15"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+
+
+------=_Part_876302
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<html><head>
+<title>eticket</title>
+</head>
+<body>
+  Yes, the text/plain part really was empty.
+</body>
+</html>
+
+------=_Part_876302--
+EOF
+
+if [ $can_reformat_texthtml -eq 1 ]; then
+  #### lynx inserts multiple blank lines, so squeeze them.
+  run_prog mhfixmsg last -replacetextplain -outfile - | \
+    squeeze_lines > "$actual"
+  check "$expected" "$actual" 'ignore space'
+else
+  rm -f "$expected"
+fi
+
+
+# check -noreplacetextplain
+cat >"$expected" <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg replacement of bad text/plain part test
+MIME-Version: 1.0
+Content-Type: multipart/alternative; boundary="----=_Part_876302"
+
+------=_Part_876302
+Content-Type: text/plain; charset="iso-8859-15"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+
+
+
+------=_Part_876302
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<html><head>
+<title>eticket</title>
+</head>
+<body>
+  Yes, the text/plain part really was empty.
+</body>
+</html>
+
+------=_Part_876302--
+EOF
+
+run_prog mhfixmsg last -replacetextplain -noreplacetextplain -outfile "$actual"
+check "$expected" "$actual"
+
+
+# check removal of extraneous trailing semicolon from header parameter list
+cat >"$expected" <<EOF
+To: recipient@example.com
+Subject: test
+From: sender@example.com
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii"
+
+test
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii";
+ name="DATE"
+Content-Description: check folded headers, with and without trailing semicolon
+Content-Disposition: attachment;
+ filename="DATE"
+
+14 April 2014
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+Subject: test
+From: sender@example.com
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii";
+
+test
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="us-ascii";
+ name="DATE"
+Content-Description: check folded headers, with and without trailing semicolon
+Content-Disposition: attachment;
+ filename="DATE";
+
+14 April 2014
+
+------- =_aaaaaaaaaa0--
+EOF
+run_test 'mhfixmsg last -outfile '"$actual" ''
 check "$expected" "$actual"
 
 
@@ -972,29 +1322,358 @@ mv "$1" "$1.backup"
 EOF
 chmod a+x "${MH_TEST_DIR}/Mail/rmmproc"
 echo "rmmproc: ${MH_TEST_DIR}/Mail/rmmproc" >>"$MH"
-cp "${MH_TEST_DIR}/Mail/inbox/15" "${MH_TEST_DIR}/Mail/inbox/15.original"
+cp "${MH_TEST_DIR}/Mail/inbox/16" "${MH_TEST_DIR}/Mail/inbox/16.original"
 
-run_test 'mhfixmsg 15' ''
-check "${MH_TEST_DIR}/Mail/inbox/15.backup" \
-      "${MH_TEST_DIR}/Mail/inbox/15.original"
+run_test 'mhfixmsg 16' ''
+check "${MH_TEST_DIR}/Mail/inbox/16.backup" \
+      "${MH_TEST_DIR}/Mail/inbox/16.original"
 
 
 # check -normmproc
-cp "${MH_TEST_DIR}/Mail/inbox/19" "${MH_TEST_DIR}/Mail/inbox/20"
+cp "${MH_TEST_DIR}/Mail/inbox/21" "${MH_TEST_DIR}/Mail/inbox/22"
 
-run_test 'mhfixmsg 19 -normmproc'
-check "${MH_TEST_DIR}/Mail/inbox/20" \
-      "${MH_TEST_DIR}/Mail/inbox/,19" 'keep first'
+run_test 'mhfixmsg 21 -normmproc'
+check "${MH_TEST_DIR}/Mail/inbox/22" \
+      "${MH_TEST_DIR}/Mail/inbox/,21" 'keep first'
 
 
 # check -rmmproc
-run_test 'mhfixmsg 20 -rmmproc true'
-if test -f '${MH_TEST_DIR}/Mail/inbox/20.backup'; then
+run_test 'mhfixmsg 21 -rmmproc true'
+if test -f '${MH_TEST_DIR}/Mail/inbox/22.backup'; then
   echo check of mhfixmsg -rmmproc FAILED, should not have created backup file
   failed=`expr ${failed:-0} + 1`
 fi
 
 
+# check -fixtype
+cat >"$expected" <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg with incorrect Content-Type
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; name="plaintext.txt"
+
+this is plain text
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg with incorrect Content-Type
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: application/octet-stream; name="plaintext.txt"
+
+this is plain text
+
+------- =_aaaaaaaaaa0--
+EOF
+
+mhfixmsg -fixtype application/octet-stream last
+check "$expected" `mhpath last`
+
+
+# check default -decodetypes
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 3
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: 8bit
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="iso-8859-1"; name="test2.txt"
+Content-Disposition: attachment; filename="test2.txt"
+Content-Transfer-Encoding: 8bit
+
+<html>
+<head>
+    This was the text/html part.
+</head>
+</body>
+</html>
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 3
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: quoted-printable
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="iso-8859-1"; name="test2.txt"
+Content-Disposition: attachment; filename="test2.txt"
+Content-Transfer-Encoding: base64
+
+PGh0bWw+CjxoZWFkPgogICAgVGhpcyB3YXMgdGhlIHRleHQvaHRtbCBwYXJ0Lgo8L2hlYWQ+Cjwv
+Ym9keT4KPC9odG1sPgo=
+
+------- =_aaaaaaaaaa0--
+EOF
+run_prog mhfixmsg last -outfile "$actual" -noreformat
+check "$expected" "$actual"
+
+
+# check -decodetypes text/plain
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 4
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: 8bit
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="iso-8859-1"; name="test2.txt"
+Content-Disposition: attachment; filename="test2.txt"
+Content-Transfer-Encoding: base64
+
+PGh0bWw+DQo8aGVhZD4NCiAgICBUaGlzIGlzIHRoZSB0ZXh0L2h0bWwgcGFydC4NCjwvaGVhZD4N
+CjwvYm9keT4NCjwvaHRtbD4NCg==
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 4
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: quoted-printable
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: text/html; charset="iso-8859-1"; name="test2.txt"
+Content-Disposition: attachment; filename="test2.txt"
+Content-Transfer-Encoding: base64
+
+PGh0bWw+DQo8aGVhZD4NCiAgICBUaGlzIGlzIHRoZSB0ZXh0L2h0bWwgcGFydC4NCjwvaGVhZD4N
+CjwvYm9keT4NCjwvaHRtbD4NCg==
+
+------- =_aaaaaaaaaa0--
+EOF
+run_prog mhfixmsg last -outfile "$actual" -decodetypes text/plain -noreformat
+check "$expected" "$actual"
+
+
+# check -decodetypes attachment/ics
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 5
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: 8bit
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: application/ics; charset="iso-8859-1"; name="invite.ics"
+Content-Disposition: attachment; filename="invite.ics"
+Content-Transfer-Encoding: 8bit
+
+BEGIN:VCALENDAR\r
+VERSION:2.0\r
+PRODID:test-mhical\r
+BEGIN:VEVENT\r
+DTSTAMP:20150101T162400Z\r
+DTSTART:20150105T160000\r
+DTEND:20150105T163000\r
+SUMMARY:4 pm meeting\r
+END:VEVENT\r
+END:VCALENDAR\r
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 5
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: quoted-printable
+
+This is the=
+ text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: application/ics; charset="iso-8859-1"; name="invite.ics"
+Content-Disposition: attachment; filename="invite.ics"
+Content-Transfer-Encoding: base64
+
+QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOnRlc3QtbWhpY2FsDQpCRUdJTjpW
+RVZFTlQNCkRUU1RBTVA6MjAxNTAxMDFUMTYyNDAwWg0KRFRTVEFSVDoyMDE1MDEwNVQxNjAwMDAN
+CkRURU5EOjIwMTUwMTA1VDE2MzAwMA0KU1VNTUFSWTo0IHBtIG1lZXRpbmcNCkVORDpWRVZFTlQN
+CkVORDpWQ0FMRU5EQVINCg==
+
+------- =_aaaaaaaaaa0--
+EOF
+run_prog mhfixmsg last -outfile "$actual" -noreformat
+check "$expected" "$actual"
+
+
+# check -decodetypes attachment/ics and -nocrlflinebreaks
+cat >$expected <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 5
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: 8bit
+
+This is the text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: application/ics; charset="iso-8859-1"; name="invite.ics"
+Content-Disposition: attachment; filename="invite.ics"
+Content-Transfer-Encoding: 8bit
+
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:test-mhical
+BEGIN:VEVENT
+DTSTAMP:20150101T162400Z
+DTSTART:20150105T160000
+DTEND:20150105T163000
+SUMMARY:4 pm meeting
+END:VEVENT
+END:VCALENDAR
+
+------- =_aaaaaaaaaa0--
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg decode test 5
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Disposition: attachment; filename="test1.txt"
+Content-MD5: kq+Hnc2SD/eKwAnkFBDuEA==
+Content-Transfer-Encoding: quoted-printable
+
+This is the=
+ text/plain part.
+
+------- =_aaaaaaaaaa0
+Content-Type: application/ics; charset="iso-8859-1"; name="invite.ics"
+Content-Disposition: attachment; filename="invite.ics"
+Content-Transfer-Encoding: base64
+
+QkVHSU46VkNBTEVOREFSDQpWRVJTSU9OOjIuMA0KUFJPRElEOnRlc3QtbWhpY2FsDQpCRUdJTjpW
+RVZFTlQNCkRUU1RBTVA6MjAxNTAxMDFUMTYyNDAwWg0KRFRTVEFSVDoyMDE1MDEwNVQxNjAwMDAN
+CkRURU5EOjIwMTUwMTA1VDE2MzAwMA0KU1VNTUFSWTo0IHBtIG1lZXRpbmcNCkVORDpWRVZFTlQN
+CkVORDpWQ0FMRU5EQVINCg==
+
+------- =_aaaaaaaaaa0--
+EOF
+run_prog mhfixmsg last -outfile "$actual" -nocrlflinebreaks -noreformat
+check "$expected" "$actual"
+
+
+# check that input is passed through to output when there's a parse error
+# (the charset string is missing its closing quote) with -outfile
+cat >"$expected.err" <<EOF
+mhfixmsg: invalid quoted-string in message 31's Content-Type: field
+          (parameter charset)
+mhfixmsg: unable to parse message 31
+EOF
+
+cat >`mhpath new` <<EOF
+To: recipient@example.com
+From: sender@example.com
+Subject: mhfixmsg pass through on parse error
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0"
+
+------- =_aaaaaaaaaa0
+Content-Type: text/plain; charset="iso-8859-1
+Content-Disposition: attachment; filename="test1.txt"
+Content-Transfer-Encoding: quoted-printable
+
+This is the=
+ text/plain part.
+
+------- =_aaaaaaaaaa0--
+EOF
+set +e
+run_prog mhfixmsg last -outfile "$actual" 2>"$actual.err"
+set -e
+#### Expected output is identical to the input message.
+check `mhpath last` "$actual" 'keep first'
+check "$expected.err" "$actual.err"
+
+
+# check that input is passed through to output when there's a parse error
+# (the charset string is missing its closing quote) with -outfile, and
+# input from stdin.  Don't check err output, because it contains the name
+# of a tmp file.  It's similar to that of the previous check.
+set +e
+run_prog mhfixmsg -file - -outfile - <`mhpath last` >"$actual" 2>/dev/null
+set -e
+#### Expected output is identical to the input message.
+check `mhpath last` "$actual"
+
+
 # make sure there are no tmp files left over
 find "$MH_TEST_DIR/Mail" \( -name 'mhfix*' -o -name ',mhfix*' \) -print \
   >"$actual"