]> diplodocus.org Git - nmh/commitdiff
If parse_mime() fails and the -file switch was used, pass the input
authorDavid Levine <levinedl@acm.org>
Sun, 12 Jun 2016 14:05:16 +0000 (10:05 -0400)
committerDavid Levine <david.levine@gonift.com>
Sun, 12 Jun 2016 14:08:07 +0000 (10:08 -0400)
message to it unchanged so that pipelines won't break.

(cherry picked from commit 564b5b785c7cc709f92a83afb547267ed7418f18)

test/mhfixmsg/test-mhfixmsg
uip/mhfixmsg.c

index cf97d5f..2194c7a 100755 (executable)
@@ -1606,6 +1606,50 @@ 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 30's Content-Type: field
+          (parameter charset)
+mhfixmsg: unable to parse message 30
+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"
index cd169df..d933163 100644 (file)
@@ -91,6 +91,7 @@ typedef struct fix_transformations {
 
 int mhfixmsgsbr (CT *, const fix_transformations *, char *);
 static int fix_boundary (CT *, int *);
+static int copy_input_to_output (char *, char *);
 static int get_multipart_boundary (CT, char **);
 static int replace_boundary (CT, char *, char *);
 static int fix_types (CT, svector_t, int *);
@@ -349,6 +350,19 @@ main (int argc, char **argv) {
         if ((ct = parse_mime (file))) {
             set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings);
             *ctp++ = ct;
+        } else {
+            advise (NULL, "unable to parse message from file %s", file);
+            status = NOTOK;
+
+            /* If there's an outfile, pass the input message unchanged, so the message won't
+               get dropped from a pipeline. */
+            if (outfile) {
+                /* Something went wrong.  Output might be expected, such as if this were run
+                   as a filter.  Just copy the input to the output. */
+                if (copy_input_to_output (file, outfile) != OK) {
+                    advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
+                }
+            }
         }
     } else {
         /*
@@ -393,6 +407,21 @@ main (int argc, char **argv) {
                 if ((ct = parse_mime (msgnam))) {
                     set_text_ctparams(ct, fx.decodetypes, fx.lf_line_endings);
                     *ctp++ = ct;
+                } else {
+                    advise (NULL, "unable to parse message %s", msgnam);
+                    status = NOTOK;
+
+                    /* If there's an outfile, pass the input message unchanged, so the message won't
+                       get dropped from a pipeline. */
+                    if (outfile) {
+                        /* Something went wrong.  Output might be expected, such as if this were run
+                           as a filter.  Just copy the input to the output. */
+                        char *input_filename = path (msgnam, TFILE);
+
+                        if (copy_input_to_output (input_filename, outfile) != OK) {
+                            advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
+                        }
+                    }
                 }
             }
         }
@@ -500,19 +529,9 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) {
         /* Something went wrong.  Output might be expected, such
            as if this were run as a filter.  Just copy the input
            to the output. */
-        int in = open (input_filename, O_RDONLY);
-        int out = strcmp (outfile, "-")
-            ?  open (outfile, O_WRONLY | O_CREAT, m_gmprot ())
-            :  STDOUT_FILENO;
-
-        if (in != -1  &&  out != -1) {
-            cpydata (in, out, input_filename, outfile);
-        } else {
-            status = NOTOK;
+        if (copy_input_to_output (input_filename, outfile) != OK) {
+            advise (NULL, "unable to copy message to %s, it might be lost\n", outfile);
         }
-
-        close (out);
-        close (in);
     }
 
     if (modify_inplace) {
@@ -527,6 +546,29 @@ mhfixmsgsbr (CT *ctp, const fix_transformations *fx, char *outfile) {
 }
 
 
+/* Copy input message to output.  Assumes not modifying in place, so this
+   might be running as part of a pipeline. */
+static int
+copy_input_to_output (char *input_filename, char *output_filename) {
+    int in = open (input_filename, O_RDONLY);
+    int out = strcmp (output_filename, "-")
+        ?  open (output_filename, O_WRONLY | O_CREAT, m_gmprot ())
+        :  STDOUT_FILENO;
+    int status = OK;
+
+    if (in != -1  &&  out != -1) {
+        cpydata (in, out, input_filename, output_filename);
+    } else {
+        status = NOTOK;
+    }
+
+    close (out);
+    close (in);
+
+    return status;
+}
+
+
 static int
 fix_boundary (CT *ct, int *message_mods) {
     struct multipart *mp;