From: David Levine Date: Sun, 12 Jun 2016 14:05:16 +0000 (-0400) Subject: If parse_mime() fails and the -file switch was used, pass the input X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/65ce050e2794a14e17b26de8096b748d51cc1f9a?ds=sidebyside If parse_mime() fails and the -file switch was used, pass the input message to it unchanged so that pipelines won't break. (cherry picked from commit 564b5b785c7cc709f92a83afb547267ed7418f18) --- diff --git a/test/mhfixmsg/test-mhfixmsg b/test/mhfixmsg/test-mhfixmsg index cf97d5ff..2194c7a2 100755 --- a/test/mhfixmsg/test-mhfixmsg +++ b/test/mhfixmsg/test-mhfixmsg @@ -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" <`mhpath new` <"$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" diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index cd169dff..d9331636 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -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;