From 21ac960a3e648cd53c155bd2b724f72f0164416f Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Fri, 17 Jun 2011 03:11:39 +0200 Subject: [PATCH] Fix mimedecode last-line omission. The mimedecode feature failed to ship the last line of the body if it was encoded as quoted-printable and had a MIME soft line break in the very last line. Reported by Lars Hecking in June 2011. Bug introduced on 1998-03-20 when the mimedecode support was added by ESR before release 4.4.1 through code contributed by Henrik Storner, in driver.c. Workaround for older releases: do not use mimedecode feature. --- NEWS | 8 ++++++++ transact.c | 59 +++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 26709e4..ac9bc42 100644 --- a/NEWS +++ b/NEWS @@ -156,6 +156,14 @@ fetchmail-6.3.23 (released 2012-12-10, 26106 LoC): * Clean up logfile vs. syslog handling, and in case logfile overrides syslog, send a message to the latter stating where logging goes. +# BUG FIXES +* The mimedecode feature failed to ship the last line of the body if it was + encoded as quoted-printable and had a MIME soft line break in the very last + line. Reported by Lars Hecking in June 2011. + Bug introduced on 1998-03-20 when the mimedecode support was added by ESR + before release 4.4.1 through code contributed by Henrik Storner. + Workaround for older releases: do not use mimedecode feature. + # CHANGES * The build process can now be made a bit more silent and concise through ./configure --enable-silent-rules, or by adding "V=0" to the make command. diff --git a/transact.c b/transact.c index ec8013a..5449e56 100644 --- a/transact.c +++ b/transact.c @@ -1383,6 +1383,28 @@ process_headers: return PS_SOCKET; } +/** Convenience function factored out from readbody(): + * send buffer \a buf via stuffline() and handle errors and progress. + * Store return value in \a *n, and return PS_IOERR for failure or + * PS_SUCCESS otherwise. */ +static int rb_send(struct query *ctl, char *buf, int *n) +{ + *n = stuffline(ctl, buf); + + if (*n < 0) + { + report(stdout, GT_("error writing message text\n")); + release_sink(ctl); + return(PS_IOERR); + } + else if (want_progress()) + { + fputc('*', stdout); + fflush(stdout); + } + return PS_SUCCESS; +} + int readbody(int sock, struct query *ctl, flag forward, int len) /** read and dispose of a message body presented on \a sock */ /** \param ctl query control record */ @@ -1478,7 +1500,7 @@ int readbody(int sock, struct query *ctl, flag forward, int len) /* ship out the text line */ if (forward && (!issoftline)) { - int n; + int n, err; inbufp = buf; /* guard against very long lines */ @@ -1486,22 +1508,31 @@ int readbody(int sock, struct query *ctl, flag forward, int len) buf[MSGBUFSIZE+2] = '\n'; buf[MSGBUFSIZE+3] = '\0'; - n = stuffline(ctl, buf); - - if (n < 0) - { - report(stdout, GT_("error writing message text\n")); - release_sink(ctl); - return(PS_IOERR); - } - else if (want_progress()) - { - fputc('*', stdout); - fflush(stdout); - } + err = rb_send(ctl, buf, &n); + if (err != PS_SUCCESS) + return err; } } + /* Flush buffer -- bug introduced by ESR on 1998-03-20 before + * release 4.4.1 when ESR did not sufficiently audit Henrik + * Storner's patch. + * Trouble reported in June 2011 by Lars Hecking, with + * text/html quoted-printable messages generated by + * Outlook/Exchange that got mutilated by fetchmail. + */ + if (forward && issoftline) + { + int n; + + /* force proper line termination */ + inbufp[0] = '\r'; + inbufp[1] = '\n'; + inbufp[2] = '\0'; + + return rb_send(ctl, buf, &n); + } + return(PS_SUCCESS); } -- 1.7.1