Module Name: src Committed By: christos Date: Fri Jan 4 01:54:55 UTC 2013
Modified Files: src/usr.bin/mail: mime_attach.c Log Message: PR/47396: Steffen: mail(1) may falsely use quoted-printable for files with embedded NULs --- mime_attach.c.orig 2013-01-03 19:26:26.000000000 +0100 +++ mime_attach.c 2013-01-03 19:42:09.000000000 +0100 @@ -224,43 +224,42 @@ is_text(const char *ctype) static const char * content_encoding_core(void *fh, const char *ctype) { + enum { + _CLEAN = 0, + _ENDWS = 1<<0, + _CTRLC = 1<<1, + _8BIT = 1<<2, + _LONGL = 1<<3 + } state = _CLEAN; + size_t maxlen = line_limit(), curlen; int c, lastc; - int ctrlchar, endwhite; - size_t curlen, maxlen; - curlen = 0; - maxlen = 0; - ctrlchar = 0; - endwhite = 0; - lastc = EOF; - while ((c = fgetc(fh)) != EOF) { + for (curlen = 0, lastc = EOF; (c = fgetc(fh)) != EOF; lastc = c) { curlen++; - if (c == '\0' || (lastc == '\r' && c != '\n')) + if (c == '\0') return MIME_TRANSFER_BASE64; if (c > 0x7f) { - if (is_text(ctype)) - return MIME_TRANSFER_QUOTED; - else + if (! is_text(ctype)) return MIME_TRANSFER_BASE64; + state |= _8BIT; + continue; } if (c == '\n') { if (is_WSP(lastc)) - endwhite = 1; + state |= _ENDWS; if (curlen > maxlen) - maxlen = curlen; + state |= _LONGL; curlen = 0; } - else if ((c < 0x20 && c != '\t') || c == 0x7f) - ctrlchar = 1; - - lastc = c; + else if ((c < 0x20 && c != '\t') || c == 0x7f || lastc == '\r') + state |= _CTRLC; } if (lastc == EOF) /* no characters read */ return MIME_TRANSFER_7BIT; - if (lastc != '\n' || ctrlchar || endwhite || maxlen > line_limit()) + if (lastc != '\n' || state != _CLEAN) return MIME_TRANSFER_QUOTED; return MIME_TRANSFER_7BIT; To generate a diff of this commit: cvs rdiff -u -r1.15 -r1.16 src/usr.bin/mail/mime_attach.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/mail/mime_attach.c diff -u src/usr.bin/mail/mime_attach.c:1.15 src/usr.bin/mail/mime_attach.c:1.16 --- src/usr.bin/mail/mime_attach.c:1.15 Thu Jan 3 20:43:59 2013 +++ src/usr.bin/mail/mime_attach.c Thu Jan 3 20:54:55 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: mime_attach.c,v 1.15 2013/01/04 01:43:59 christos Exp $ */ +/* $NetBSD: mime_attach.c,v 1.16 2013/01/04 01:54:55 christos Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #include <sys/cdefs.h> #ifndef __lint__ -__RCSID("$NetBSD: mime_attach.c,v 1.15 2013/01/04 01:43:59 christos Exp $"); +__RCSID("$NetBSD: mime_attach.c,v 1.16 2013/01/04 01:54:55 christos Exp $"); #endif /* not __lint__ */ #include <assert.h> @@ -224,12 +224,18 @@ is_text(const char *ctype) static const char * content_encoding_core(void *fh, const char *ctype) { - int c, lastc; +#define MAILMSG_CLEAN 0x0 +#define MAILMSG_ENDWS 0x1 +#define MAILMSG_CTRLC 0x2 +#define MAILMSG_8BIT 0x4 +#define MAILMSG_LONGL 0x8 + int c, lastc, state; int ctrlchar, endwhite; size_t curlen, maxlen; + state = MAILMSG_CLEAN; curlen = 0; - maxlen = 0; + maxlen = line_limit(); ctrlchar = 0; endwhite = 0; lastc = EOF; @@ -240,27 +246,26 @@ content_encoding_core(void *fh, const ch return MIME_TRANSFER_BASE64; if (c > 0x7f) { - if (is_text(ctype)) - return MIME_TRANSFER_QUOTED; - else + if (!is_text(ctype)) return MIME_TRANSFER_BASE64; + state |= MAILMSG_8BIT; + continue; } if (c == '\n') { if (is_WSP(lastc)) - endwhite = 1; + state |= MAILMSG_ENDWS; if (curlen > maxlen) - maxlen = curlen; + state |= MAILMSG_LONGL; curlen = 0; } else if ((c < 0x20 && c != '\t') || c == 0x7f || lastc == '\r') - ctrlchar = 1; - + state |= MAILMSG_CTRLC; lastc = c; } if (lastc == EOF) /* no characters read */ return MIME_TRANSFER_7BIT; - if (lastc != '\n' || ctrlchar || endwhite || maxlen > line_limit()) + if (lastc != '\n' || state != MAILMSG_CLEAN) return MIME_TRANSFER_QUOTED; return MIME_TRANSFER_7BIT;