From: Ken Hornstein Date: Sat, 1 Feb 2014 17:48:20 +0000 (-0500) Subject: Merge branch 'base64-text-fixup' X-Git-Url: https://diplodocus.org/git/nmh/commitdiff_plain/95dfab96c02e8252eafda2b311747578ef0af456?hp=32355995bdbda4a224971e0532aa3b7a8edb9370 Merge branch 'base64-text-fixup' --- diff --git a/h/prototypes.h b/h/prototypes.h index 563a0d5d..e8be9fe6 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -362,7 +362,20 @@ int SOprintf (char *, ...); int what_now (char *, int, int, char *, char *, int, struct msgs *, char *, int, char *, int); int WhatNow(int, char **); -int writeBase64aux(FILE *, FILE *); + +/* + * Copy data from one file to another, converting to base64-encoding. + * + * Arguments include: + * + * in - Input filehandle (unencoded data) + * out - Output filename (base64-encoded data) + * crlf - If set, output encoded CRLF for every LF on input. + * + * Returns OK on success, NOTOK otherwise. + */ +int writeBase64aux(FILE *in, FILE *out, int crlf); + int writeBase64 (unsigned char *, size_t, unsigned char *); int writeBase64raw (unsigned char *, size_t, unsigned char *); diff --git a/sbr/base64.c b/sbr/base64.c index 5ff9f53c..6682c3f3 100644 --- a/sbr/base64.c +++ b/sbr/base64.c @@ -13,10 +13,10 @@ static char nib2b64[0x40+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int -writeBase64aux (FILE *in, FILE *out) +writeBase64aux (FILE *in, FILE *out, int crlf) { unsigned int cc, n; - char inbuf[3]; + unsigned char inbuf[3]; n = BPERLIN; while ((cc = fread (inbuf, sizeof(*inbuf), sizeof(inbuf), in)) > 0) { @@ -29,6 +29,36 @@ writeBase64aux (FILE *in, FILE *out) if (cc < sizeof(inbuf) - 1) inbuf[1] = 0; } + + /* + * Convert a LF to a CRLF if desired. That means we need to push + * data back into the input stream. + */ + + if (crlf) { + unsigned int i; + + for (i = 0; i < cc; i++) { + if (inbuf[i] == '\n') { + inbuf[i] = '\r'; + /* + * If it's the last character in the buffer, we can just + * substitute a \r and push a \n back. Otherwise shuffle + * everything down and push the last character back. + */ + if (i == cc - 1) { + ungetc('\n', in); + } else { + /* This only works as long as sizeof(inbuf) == 3 */ + ungetc(inbuf[cc - 1], in); + if (cc == 3 && i == 0) + inbuf[2] = inbuf[1]; + inbuf[++i] = '\n'; + } + } + } + } + bits = (inbuf[0] & 0xff) << 16; bits |= (inbuf[1] & 0xff) << 8; bits |= inbuf[2] & 0xff; diff --git a/test/mhfixmsg/test-mhfixmsg b/test/mhfixmsg/test-mhfixmsg index 9df3f657..aa8c9514 100755 --- a/test/mhfixmsg/test-mhfixmsg +++ b/test/mhfixmsg/test-mhfixmsg @@ -558,7 +558,7 @@ check "$expected" "$actual" # check attempted -decode of binary text #### Generated the encoded text below with: -#### $ printf '\x0d\xbd\xb2=\xbc\n' | base64 +#### $ printf '\x0\xbd\xb2=\xbc\n' | base64 cat >`mhpath new` <c_ceopenfnx) (ct, &file)) == NOTOK) return NOTOK; - result = writeBase64aux (ce->ce_fp, out); + result = writeBase64aux (ce->ce_fp, out, (ct->c_type == CT_TEXT)); (*ct->c_ceclosefnx) (ct); return result; } diff --git a/uip/mhparse.c b/uip/mhparse.c index 371d0c92..d12fbb30 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -1677,7 +1677,7 @@ static int openBase64 (CT ct, char **file) { int bitno, cc, digested; - int fd, len, skip, own_ct_fp = 0; + int fd, len, skip, own_ct_fp = 0, text = ct->c_type == CT_TEXT; uint32_t bits; unsigned char value, b; char *cp, *ep, buffer[BUFSIZ]; @@ -1789,17 +1789,20 @@ openBase64 (CT ct, char **file) test_end: if ((bitno -= 6) < 0) { b = (bits >> 16) & 0xff; - putc ((char) b, ce->ce_fp); + if (!text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); if (skip < 2) { b = (bits >> 8) & 0xff; - putc ((char) b, ce->ce_fp); + if (! text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); if (skip < 1) { b = bits & 0xff; - putc ((char) b, ce->ce_fp); + if (! text || b != '\r') + putc ((char) b, ce->ce_fp); if (digested) MD5Update (&mdContext, &b, 1); } diff --git a/uip/viamail.c b/uip/viamail.c index 97dee86b..0ff765c4 100644 --- a/uip/viamail.c +++ b/uip/viamail.c @@ -190,7 +190,7 @@ via_mail (char *mailsw, char *subjsw, char *parmsw, char *descsw, if (fflush (fp)) adios (tmpfil, "error writing to"); - writeBase64aux (stdin, fp); + writeBase64aux (stdin, fp, 0); if (fflush (fp)) adios (tmpfil, "error writing to");