]> diplodocus.org Git - nmh/commitdiff
mhfixmsg now removes an extraneous trailing semicolon from header
authorDavid Levine <levinedl@acm.org>
Mon, 1 Dec 2014 03:35:19 +0000 (21:35 -0600)
committerDavid Levine <levinedl@acm.org>
Mon, 1 Dec 2014 03:35:19 +0000 (21:35 -0600)
parameter lists.

docs/pending-release-notes
man/mhfixmsg.man
test/mhfixmsg/test-mhfixmsg
uip/mhfixmsg.c
uip/mhparse.c

index cf247dee713717e72ebb87ccb0b7d1790593f1a2..fe12e698f1530d7057dc84bb841903af33764724 100644 (file)
@@ -26,6 +26,8 @@ NEW FEATURES
   nmh installation if it finds one in your $PATH.
 - Added getmymbox and getmyaddr mh-format(5) function escapes.
 - The -changecur and -nochangecur switches have been added to mhfixmsg(1).
+- mhfixmsg now removes an extraneous trailing semicolon from header
+  parameter lists.
 
 -----------------
 OBSOLETE FEATURES
index d954c00671a118d5e4474822a15166c5c410a1ad..3bb8e84eb20dd147e0a49058100f8f5d093e9c26 100644 (file)
@@ -1,4 +1,4 @@
-.TH MHFIXMSG %manext1% "November 22, 2014" "%nmhversion%"
+.TH MHFIXMSG %manext1% "November 30, 2014" "%nmhversion%"
 .\"
 .\" %nmhwarning%
 .\"
@@ -149,6 +149,10 @@ and other
 .B nmh
 programs that parse MIME messages.
 .PP
+.B mhfixmsg
+applies one transformation unconditionally:  it removes an extraneous
+trailing semicolon from the parameter lists of MIME header fields.
+.PP
 The
 .B \-verbose
 switch directs
index 594793a656ff557b43008b9c29e6a99293c34316..cc69aea7a6ffcd9d7aa3e1bfab22e74e4f438dbc 100755 (executable)
@@ -1029,6 +1029,58 @@ 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"
+
+
 # check rmmproc
 cat >"$MH_TEST_DIR/Mail/rmmproc" <<'EOF'
 mv "$1" "$1.backup"
index f23d26d91b02fc3a76ad00ca6f008d5253458fce..307aba5aef6173081d263bde4b7ef40ec2b8fdc8 100644 (file)
@@ -55,6 +55,9 @@ int debugsw; /* Needed by mhparse.c. */
 extern int skip_mp_cte_check;                 /* flag to InitMultiPart */
 extern int suppress_bogus_mp_content_warning; /* flag to InitMultiPart */
 extern int bogus_mp_content;                  /* flag from InitMultiPart */
+/* flags to/from parse_header_attrs */
+extern int suppress_extraneous_trailing_semicolon_warning;
+extern int extraneous_trailing_semicolon;
 
 /* mhoutsbr.c */
 int output_message (CT, char *);
@@ -101,6 +104,7 @@ static int decode_text_parts (CT, int, int *);
 static int content_encoding (CT, const char **);
 static int strip_crs (CT, int *);
 static int convert_charsets (CT, char *, int *);
+static int fix_always (CT, int *);
 static int write_content (CT, char *, char *, int, int);
 static int remove_file (char *);
 static void report (char *, char *, char *, char *, ...);
@@ -258,6 +262,7 @@ main (int argc, char **argv) {
     }
 
     suppress_bogus_mp_content_warning = skip_mp_cte_check = 1;
+    suppress_extraneous_trailing_semicolon_warning = 1;
 
     if (! context_find ("path"))
         free (path ("./", TFOLDER));
@@ -405,6 +410,7 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) {
     }
 
     reverse_alternative_parts (*ctp);
+    status = fix_always (*ctp, &message_mods);
     if (status == OK  &&  fx->fixboundary) {
         status = fix_boundary (ctp, &message_mods);
     }
@@ -1846,6 +1852,69 @@ convert_charsets (CT ct, char *dest_charset, int *message_mods) {
 }
 
 
+/*
+ * Fix various problems that aren't handled elsewhere.  These
+ * are fixed unconditionally:  there are no switches to disable
+ * them.  (Currently, "problems" is just one:  an extraneous
+ * semicolon at the end of a header parameter list.)
+ */
+static int
+fix_always (CT ct, int *message_mods) {
+    int status = OK;
+
+    switch (ct->c_type) {
+    case CT_MULTIPART: {
+        struct multipart *m = (struct multipart *) ct->c_ctparams;
+        struct part *part;
+
+        for (part = m->mp_parts; status == OK  &&  part; part = part->mp_next) {
+            status = fix_always (part->mp_part, message_mods);
+        }
+        break;
+    }
+
+    case CT_MESSAGE:
+        if (ct->c_subtype == MESSAGE_EXTERNAL) {
+            struct exbody *e = (struct exbody *) ct->c_ctparams;
+
+            status = fix_always (e->eb_content, message_mods);
+        }
+        break;
+
+    default: {
+        HF hf;
+
+        for (hf = ct->c_first_hf; hf; hf = hf->next) {
+            const size_t len = strlen (hf->value);
+
+            if (hf->value[len - 1] == '\n'  &&  hf->value[len - 2] == ';') {
+                /* Remove trailing ';' from parameter value. */
+                hf->value[len - 2] = '\n';
+                hf->value[len - 1] = '\0';
+
+                /* Also, if Content-Type parameter, remove trailing ';'
+                   from ct->c_ctline.  This probably isn't necessary
+                   but can't hurt. */
+                if (strcasecmp (hf->name, "Content-Type") == 0  &&
+                    ct->c_ctline  &&
+                    ct->c_ctline[strlen(ct->c_ctline) - 1] == ';') {
+                    ct->c_ctline[strlen(ct->c_ctline) - 1] = '\0';
+                }
+
+                ++*message_mods;
+                if (verbosw) {
+                    report (NULL, ct->c_partno, ct->c_file,
+                            "remove trailing ; from %s parameter value",
+                            hf->name);
+                }
+            }
+        }
+    }}
+
+    return status;
+}
+
+
 static int
 write_content (CT ct, char *input_filename, char *outfile, int modify_inplace,
                int message_mods) {
index a499834568f7ab5d7453ab741fae40df6c5b9057..96af58e9e04327364103a7a6ff12321aa8821cbf 100644 (file)
@@ -34,10 +34,14 @@ int checksw = 0;    /* check Content-MD5 field */
  * 1) Instruct parser not to detect invalid Content-Transfer-Encoding
  *    in a multipart.
  * 2) Suppress the warning about bogus multipart content, and report it.
+ * 3) Suppress the warning about extraneous trailing ';' in header parameter
+ *    lists, and report it.
  */
 int skip_mp_cte_check;
 int suppress_bogus_mp_content_warning;
 int bogus_mp_content;
+int suppress_extraneous_trailing_semicolon_warning;
+int extraneous_trailing_semicolon;
 
 /*
  * Structures for TEXT messages
@@ -3276,10 +3280,13 @@ parse_header_attrs (const char *filename, const char *fieldname,
         }
 
        if (*cp == 0) {
-           advise (NULL,
-                   "extraneous trailing ';' in message %s's %s: "
-                    "parameter list",
-                   filename, fieldname);
+           if (! suppress_extraneous_trailing_semicolon_warning) {
+               advise (NULL,
+                       "extraneous trailing ';' in message %s's %s: "
+                       "parameter list",
+                       filename, fieldname);
+           }
+           extraneous_trailing_semicolon = 1;
            return DONE;
        }